﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><channel><title>Altriva Team Blog</title><link>http://www.altriva.com/</link><description>Altriva Solutions Blog - CRM (Microsoft Dynamics CRM), SharePoint (MOSS), Application Development, and Integration Solutions.</description><copyright>Copyright 2010 by Altriva LLC</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>Ingen.NukePress (www.nukepress.net)</generator><language>en-US</language><trackback:ping /><item><title>Microsoft Dynamics CRM 2011 Beta Available for Public Download</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/31/Microsoft-Dynamics-CRM-2011-Beta-Available-for-Public-Download.aspx</link><author>Altriva</author><guid isPermaLink="false">31</guid><pubDate>Thu, 09 Sep 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft has released the public beta for Microsoft Dynamics CRM 2011 (Code name CRM 5) which also means the Non-Disclosure Agreement that prevented Altriva from discussing CRM 2011 details is no longer in effect. We’ve been working with earlier builds of CRM 2011 for months, and we’re excited to share with you what the new release has to offer. Stay tuned for updates.</p>
<div style="margin: 0in 0in 10pt">Get involved by participating in the Microsoft Dynamics CRM 2011 Beta forum: <a href="http://social.microsoft.com/Forums/en-US/crm2011beta/threads">http://social.microsoft.com/Forums/en-US/crm2011beta/threads</a></div>
<div style="margin: 0in 0in 10pt">Download the installation files and implementation guide documentation from Microsoft: <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=0c7dcc45-9d41-4e2e-8126-895517b4274c&displayLang=en">http://www.microsoft.com/downloads/en/details.aspx?FamilyID=0c7dcc45-9d41-4e2e-8126-895517b4274c&displayLang=en</a></div>
<div style="margin: 0in 0in 10pt">See an interactive demo screencast put on by XRM Virtual and Microsoft: <a href="http://www.screencast.com/users/coloradojules/folders/Default/media/094c821f-c71f-448d-88bf-5b627b586004">http://www.screencast.com/users/coloradojules/folders/Default/media/094c821f-c71f-448d-88bf-5b627b586004</a></div>
<div style="margin: 0in 0in 10pt">Here’s a teaser of new application features copied from the Microsoft Dynamics CRM 2011 Beta Implementation Guide:</div>
<div style="margin: 0in 0in 10pt">New application features</div>
<div style="margin: 0in 0in 10pt">•             Visualization. On demand graphical charts for many record types.</div>
<div style="margin: 0in 0in 10pt">•             Improved user interface that includes the Office Ribbon design and more streamlined forms.</div>
<div style="margin: 0in 0in 10pt">•             Connections. A new feature for establishing relationships between records.</div>
<div style="margin: 0in 0in 10pt">•             Recurring activities. Schedule activities, such as appointments, that repeat.</div>
<div style="margin: 0in 0in 10pt">•             Queue enhancements.</div>
<div style="margin: 0in 0in 10pt">•             Record level Auditing.</div>
<div style="margin: 0in 0in 10pt">•             Field level security. Manage user and team permissions to read, create, or write information in secured fields.</div>
<div style="margin: 0in 0in 10pt">•             Solutions. Solutions are packages of software that you can install or remove from your Microsoft Dynamics CRM organization.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 10pt 0.5in"><span>-<span style="font: 7pt 'Times New Roman'">          </span></span>Phil Edry</div>
<p>UPDATE: Developer documentation can be found here: <a href="http://offers.crmchoice.com/CRM2011Beta-Developer-Videos/#content780">http://offers.crmchoice.com/CRM2011Beta-Developer-Videos/#content780</a></p>]]></content:encoded><trackback:ping /></item><item><title>A great mix of old and new: EDI and Windows Azure</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/30/A-great-mix-of-old-and-new:-EDI-and-Windows-Azure.aspx</link><author>Tim Dutcher</author><guid isPermaLink="false">30</guid><pubDate>Mon, 09 Aug 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>At one point during my career, I worked on building, parsing, and transmitting Electronic Data Interchange (EDI) files daily, mostly for the healthcare industry.&#160; Recently, I had the opportunity to help a manufacturing company create and send EDI to their shipping/fulfillment provider and receive EDI back to update their order processing system.</p>
<p>Prior to implementing EDI, the manufacturer would receive orders from an ASP.NET-based web site into their Dynamics CRM Online instance. A workflow in CRM would then create a packing list and send the information as an e-mail message to the shipping company.</p>
<p>As you might expect, the shipping company had to open the e-mail and manually re-type the order details into their system so that the warehouse could pick the items from the shelves and ship them out.&#160; This led to high costs for the manufacturer, the possibility of mistyped information, and order fulfillment delays.</p>
<p>In addition to the high costs incurred by the manufacturer and the other problems with manual intervention of the ordering process, the company is experiencing rapid growth in sales. Although this is great news, especially in the current economic climate, their rapid growth also meant that the order fulfillment process had even more risk of breaking down.</p>
<p>Like a lot of companies in the manufacturing and shipping industries, beginning in the mid-1960s, the shipping company used by our client (the product manufacturer) supports EDI for receiving shipment requests and sending back shipment details.&#160; With the rapid growth of our client, it made perfect sense to move to an EDI-based solution.</p>
<p>The diagrams to follow show the ordering and fulfillment process before and after Altriva helped our client improve the process.</p>
<p><img alt="Original Ordering and Shipping Process" align="left" width="666" height="681" src="/Portals/0/Blogs/EDIAZURE/crh_orig.png" /></p>
<p><br />
&#160;</p>
<p><img alt="Enhanced Ordering and Shipping Process" align="left" width="666" height="681" src="/Portals/0/Blogs/EDIAZURE/crh_new.png" /></p>
<p><br />
&#160;</p>
<p>Altriva and our client had many reasons to choose Windows Azure for the platform to host the EDI-processing application. First, as I mentioned previously, our client’s sales are growing at such a rate that we needed a platform that can scale-up quickly. Azure provides fast and easy scalability. Next, the application needs to run reliably 24x7x365 and Azure has proven to provide excellent reliability. Finally, since our client already subscribes to Microsoft Dynamics CRM Online and other Microsoft services, they receive a single billing statement for their use of Windows Azure as well.</p>
<p>On the surface, combining “EDI” and “Windows Azure” in the same sentence seems preposterous, but in practice the two can work together quite well. Maybe next I’ll get to work on a project that combines EBCDIC and Microsoft LightSwitch!&#160; Or maybe not.<br />
&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>Microsoft Dynamics CRM 4.0: Rollup 11 – Important fixes for Outlook 2010 and SQL Server 2008 Reporting Services</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/29/Microsoft-Dynamics-CRM-4.0:-Rollup-11-–-Important-fixes-for-Outlook-2010-and-SQL-Server-2008-Reporting-Services.aspx</link><author>Altriva</author><guid isPermaLink="false">29</guid><pubDate>Thu, 15 Jul 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft CRM 4.0 Update Rollup 11 is now available.&#160;Released June 3rd, this cumulative update includes important updates for Outlook 2010 and SSRS 2008. Altriva recommends installing this update across all roles if your organization leverages Outlook 2010 or if your SSRS Reports Server uses SQL Server 2008.&#160;Rollup 7 is a prerequisite for installing the Update for the Outlook client and Data Migration Manager.</p>
<div style="margin: 0in 0in 10pt">For more information on the contents and procedure for installing Update 11, Follow the link to the <a href="http://support.microsoft.com/kb/981328/en-us">Microsoft Support Site</a>.&#160;To download Rollup 11, follow the link to the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=f84f2bfb-393d-4b90-bf1b-300a82ec6083">Microsoft Download Site</a>.</div>
<div style="margin: 0in 0in 10pt">Below is sample XML for registering Rollup 11 for the Client for Outlook. We recommend leaving Rollup 7 as a mandatory rollup for Outlook and leaving Rollup 11 as optional. The XML below also shows how to delete Rollup 10 from the available updates. Note that Vista and Windows 7 users may need to check for updates as Administrator for the update to install correctly. This can be done by running Outlook as Administrator and selecting “Check for Updates” in the CRM menu once the CRM Add-in has connected.</div>
<div style="margin: 0in 0in 10pt">&lt;ClientPatches&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Create&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ClientPatchInfo&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;PatchId&gt;{77F3EBA0-20E8-403E-B43B-E5AC633E139E}&lt;/PatchId&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Title&gt;Update Rollup 11 for Microsoft Dynamics CRM 4.0 (Optional)&lt;/Title&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Description&gt;Update Rollup 11 for Microsoft Dynamics CRM 4.0 (Optional)&lt;/Description&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;IsMandatory&gt;false&lt;/IsMandatory&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;IsEnabled&gt;true&lt;/IsEnabled&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ClientType&gt;OutlookLaptop, OutlookDesktop&lt;/ClientType&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;!--- *** The LinkId is different for every Language.&#160; Please see the KB Article for the correct Link ID to use --&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;!-- &amp; in xml documents must be escaped using &amp;amp; --&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;LinkId&gt;192046&amp;amp;clcid=0x409&lt;/LinkId&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/ClientPatchInfo&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Create&gt;<br />
&lt;!-- ONLY Include this section if you previously registered rollup 10 and would like to delete it --&gt;<br />
&lt;!-- Otherwise remove the delete section --&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Delete&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;PatchId&gt;{C853A15A-5546-4F07-BF41-FC1C64570AB3}&lt;/PatchId&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Delete&gt;<br />
&lt;/ClientPatches&gt;<br />
<br />
Instructions for registering Outlook Client updates can be found in the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1ceb5e01-de9f-48c0-8ce2-51633ebf4714&amp;DisplayLang=en">Implementation Guide: Operating</a> Page 9.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 10pt 0.5in"><span>-<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Phil Edry</div>
<p>&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>When configuring the Outlook Client, you receive the error "Mandatory updates for Microsoft Dynamics CRM could not be applied successfully.  Try running the application again."</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/28/When-configuring-the-Outlook-Client,-you-receive-the-error-"Mandatory-updates-for-Microsoft-Dynamics-CRM-could-not-be-applied-successfully.--Try-running-the-application-again.".aspx</link><author>Altriva</author><guid isPermaLink="false">28</guid><pubDate>Thu, 15 Jul 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Here’s a quick gotcha I saw on the <a href="http://social.microsoft.com/Forums/en-US/crm/thread/3ae160b9-aeb4-498e-8cac-1774cd6bd1ec">CRM Forums</a>. When configuring the CRM Client for Outlook, you enter http://servername:port/ORGNAME in the Internet address field and you get a cryptic error stating “Mandatory updates for Microsoft Dynamics CRM could not be applied successfully.  Try running the application again.”</p>
<p><img alt="Unhelpful error message." width="642" height="461" src="/Portals/0/Updates.png" /></p>
<p>This confusing message only appears if you include the ORGNAME as part of your CRM server URL. To resolve this issue, simply delete the ORGNAME from you URL (http://servername:port/). Don’t worry if your user has access to more than one CRM Organization – the configuration wizard will prompt you to choose an Organization after you click next.</p>
<p><br />
- Phil Edry <br />
 </p>]]></content:encoded><trackback:ping /></item><item><title>Microsoft Dynamics CRM 4.0: Rollup 10</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/27/Microsoft-Dynamics-CRM-4.0:-Rollup-10.aspx</link><author>Justin Mathena</author><guid isPermaLink="false">27</guid><pubDate>Fri, 23 Apr 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<div>Microsoft CRM 4.0 Update Rollup&#160;10 is now available.&#160; Released April 8th, this cumulative update includes fixes for&#160;roughly 5 issues&#160;with install&#160;packages for the CRM&#160;server, CRM&#160;Data Migration&#160;Manager, CRM E-mail Router,&#160;and the&#160;CRM&#160;Outlook client.&#160; Rollup 7 is a prerequisite for installing the Update.<br />
&#160;<br />
For more information on the contents and procedure for installing Update 10, Follow the link to the <a href="http://support.microsoft.com/kb/979347">Microsoft Support Site</a>.&#160; To download Rollup 10, follow the link to the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=5da4d352-1d3f-4426-9c17-b256c30afdb9&amp;displayLang=en">Micrsoft Download Site</a>.</div>]]></content:encoded><trackback:ping /></item><item><title>Activity Reassignment Error</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/26/Activity-Reassignment-Error.aspx</link><author>Phil Edry</author><guid isPermaLink="false">26</guid><pubDate>Wed, 31 Mar 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<div>Ever try reassigning an Activity like a task or appointment and get an error stating "The logged-on user does not have the appropriate security permissions to view these records or perform the specific action"?&#160; You're sure that you have the appropriate "Append" and "Append To" permissions set up on the User entity and the Activity entity you want to re-assign, but you still receive the following error:</div>
<div>&#160;<img alt="CRM Error Message" width="500" height="286" src="/Portals/0/Blogs/Security Permissions Error.png" /></div>
<div>Well, since Activities can be assigned to Queues, you’ll need to make sure that one of your user roles has the read permission on the Queue record.</div>
<div>&#160;<img alt="Potential Security Settings" width="500" height="32" src="/Portals/0/Blogs/Security Permissions Error Blog 2.png" /></div>
<div>Change the above row to look like the below row.</div>
<div>&#160;<img alt="" width="500" height="35" src="/Portals/0/Blogs/Security Permissions Error Blog 3.png" /></div>
<div>I hope this "gotcha" blog entry helps!</div>
<div>&#160;</div>
<div>-Phil Edry</div>
<p>&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>Microsoft Releases Update Rollup 9 for Dynamics CRM 4.0</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/22/Microsoft-Releases-Update-Rollup-9-for-Dynamics-CRM-4.0.aspx</link><author>Justin Mathena</author><guid isPermaLink="false">22</guid><pubDate>Thu, 11 Feb 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft Update Rollup 9 for Dynamics CRM 4.0 is now available.&#160; Released Feb 11, this update includes packages for the server, Outlook client and E-mail Router.&#160; Rollup 7 is a prerequisite for installing the Update.<br />
<br />
For more information on the contents and procedure for installing Update 9, Follow this link to the <a target="_blank" href="http://support.microsoft.com/default.aspx?kbid=977650">Microsoft Support Site</a>.&#160; To download Rollup 9, follow this link to the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=5869f2b3-d1a0-4f71-8be3-fde6e8053a2e">Micrsoft Download Site</a>.</p>]]></content:encoded><trackback:ping /></item><item><title>Using SQL Server Identity columns to implement Custom Entity numbering</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/24/Using-SQL-Server-Identity-columns-to-implement-Custom-Entity-numbering.aspx</link><author>Phil Edry</author><guid isPermaLink="false">24</guid><pubDate>Thu, 28 Jan 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>NOTE:&#160; This entry assumes the reader has experience implementing and deploying MS CRM 4.0 plug-ins. More detailed information on how to develop and deploy plug-ins is available here:&#160;<a target="_blank" href="http://www.altriva.com/AltrivaBlog/PostID/7.aspx">Altriva Blog - Execution&#160;Pipeline Overview</a>&#160;and here: <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc151098.aspx">MSDN-Registering Plug-ins</a>.</p>
<div>Using SQL Server to generate auto-incrementing numbers is a simple way to avoid number generation risks like number collision, where two entities could be assigned the same number. The procedure flow for generating auto-incrementing entity numbers is as follows:</div>
<ol>
    <li><font size="2">When a user creates a new entity, a plug-in registered on pre-create or post-create of that entity fires.</font></li>
    <li><font size="2">The plug-in confirms that the correct entity fired the plug-in.</font></li>
    <li><font size="2">The plug-in then calls a stored procedure to insert a row into a table with an auto-incrementing identity column. If the plug-in was registered on post-create of the entity, the GUID of the entity can be inserted into the table for future reference.</font></li>
    <li><font size="2">The stored procedure then selects the generated identity for that row and returns it to the plug-in.</font></li>
    <li><font size="2">The plug-in then sets an attribute on the entity to the identity and returns.</font></li>
</ol>
<p>A separate plug-in must be created and registered for each entity that uses auto-numbering. However, it is up to the implementer whether to use one table to generate all auto-numbering or to create separate tables and stored procedures for each entity. Using one table would mean all entities would share the same sequence of numbers, while using multiple tables would allow each entity to start at “1” and have its own sequence.</p>
<p>I suggest creating the table and stored procedure in the MSCRM database with unique names. While creating database objects in the MSCRM database is unsupported, it allows for much simpler system backups and deployment maintenance when working with multiple environments. Care should be taken in naming tables and stored procedures to avoid naming the objects something that Microsoft might use in future versions of CRM.</p>
<p>Below is the plug-in and stored procedure code for an implementation of auto-numbering for the opportunity entity. The plug-in is registered on pre-create due to a client’s requirement that the displayed opportunity name “new_name” be updated and displayed on save with the auto-number appended. The plug-in stores the auto-number in the “name” attribute. Note that the connection string is hardcoded in this sample code, so changing database servers would require a recompilation of the plug-in. Be sure to modify the connection string as appropriate.</p>
<hr />
<div style="margin: 0in 0in 10pt"><span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Collections.Generic;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Text;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> Microsoft.Crm.Sdk;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> Microsoft.Crm.SdkTypeProxy;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Data;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Data.SqlTypes;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Data.SqlClient;</span><br />
<span style="line-height: 115%; color: blue; font-size: 8pt">using</span><span style="line-height: 115%; font-size: 8pt"> System.Web.Services;<br />
<br />
<span style="line-height: 115%; color: blue; font-size: 8pt">namespace</span><span style="line-height: 115%; font-size: 8pt"> Altriva.CRM.Plugins</span><br />
<span style="line-height: 115%; font-size: 8pt">{</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">OpportunityCreateHandler</span>: <span style="color: #2b91af">IPlugin</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160; {</span><span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> Execute(<span style="color: #2b91af">IPluginExecutionContext</span> context)</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">DynamicEntity</span> entity = <span style="color: blue">null</span>;</span>&#160;<br />
</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Check whether the input parameters property bag contains a target</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// of the create operation and that target is of type DynamicEntity.</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (context.InputParameters.Properties.Contains(<span style="color: #a31515">"Target"</span>) &amp;&amp;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; context.InputParameters.Properties[<span style="color: #a31515">"Target"</span>] <span style="color: blue">is</span> <span style="color: #2b91af">DynamicEntity</span>)</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Obtain the target business entity from the input parmameters.</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; entity = (<span style="color: #2b91af">DynamicEntity</span>)context.InputParameters.Properties[<span style="color: #a31515">"Target"</span>];</span>&#160;<br />
<br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Verify that the entity represents an opportunity.</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (entity.Name != <span style="color: #2b91af">EntityName</span>.opportunity.ToString()) { <span style="color: blue">return</span>; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span>;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span>&#160;<br />
<br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">try</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">int</span> sequentialId = 0;</span><br />
<br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span> connectionString = <span style="color: #a31515">"Data Source=&lt;Data source&gt;;Initial Catalog=&lt;Organization Name&gt;_MSCRM;Integrated Security=sspi"</span>;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">SqlConnection</span> conn = <span style="color: blue">new</span> <span style="color: #2b91af">SqlConnection</span>(connectionString);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">SqlCommand</span> cmd = <span style="color: blue">new</span> <span style="color: #2b91af">SqlCommand</span>(<span style="color: #a31515">"Altrivacustp_GenerateUniqueId"</span>, conn);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cmd.CommandType = <span style="color: #2b91af">CommandType</span>.StoredProcedure;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cmd.Parameters.AddWithValue(<span style="color: #a31515">"@objectID"</span>, <span style="color: blue">null</span>);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; conn.Open();</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sequentialId = (<span style="color: blue">int</span>)cmd.ExecuteScalar();</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; conn.Close();</span>&#160;<br />
<br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (entity.Properties.Contains(<span style="color: #a31515">"name"</span>) == <span style="color: blue">false</span>)&#160;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">StringProperty</span> opportunityID = <span style="color: blue">new</span> <span style="color: #2b91af">StringProperty</span>(<span style="color: #a31515">"name"</span>, sequentialId.ToString());</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; entity.Properties.Add(opportunityID);</span>&#160;<br />
<br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color: blue">if</span> (entity.Properties.Contains(<span style="color: #a31515">"new_name"</span>) == <span style="color: blue">true</span>)</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">StringProperty</span> opportunityName = <span style="color: blue">new</span> <span style="color: #2b91af">StringProperty</span>(<span style="color: #a31515">"new_name"</span>, sequentialId.ToString() + <span style="color: #a31515">" - "</span> + entity.Properties[<span style="color: #a31515">"new_name"</span>]);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; entity.Properties.Remove(<span style="color: #a31515">"new_name"</span>);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; entity.Properties.Add(opportunityName);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Throw an error, because Opportunity ID must be system generated</span></span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #2b91af">InvalidPluginExecutionException</span>(<span style="color: #a31515">"The Opportunity ID can only be set by the system"</span>);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span>;</span><br />
<br />
&#160;<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">catch</span> (System.Web.Services.Protocols.<span style="color: #2b91af">SoapException</span> ex)</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #2b91af">InvalidPluginExecutionException</span>(</span><span style="line-height: 115%; font-size: 8pt"><span style="color: #a31515">"An error occurred in the OpportunityCreateHandler plug-in."</span>, ex);</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160; }</span><br />
<span style="line-height: 115%; font-size: 8pt">}</span></div>
<hr />
<p>Table Creation and Stored Procedure Code:</p>
<hr />
<div><span style="line-height: 115%; color: green; font-size: 8pt"><font color="#808080">GO<br />
</font>/****** Object:&#160;Table [dbo].[Altrivacustp_OpportunityNumber]&#160;&#160;&#160; Script Date: 05/07/2008 14:28:54 ******/<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">IF</span><span style="line-height: 115%; font-size: 8pt">&#160;<span style="color: gray">EXISTS</span> <span style="color: gray">(</span><span style="color: blue">SELECT</span> <span style="color: gray">*</span> <span style="color: blue">FROM</span> <span style="color: green">sys.objects</span> <span style="color: blue">WHERE</span> <span style="color: fuchsia">object_id</span> <span style="color: gray">=</span> <span style="color: fuchsia">OBJECT_ID</span><span style="color: gray">(</span>N<span style="color: red">'[dbo].[Altrivacustp_OpportunityNumber]'</span><span style="color: gray">)</span> <span style="color: gray"><span style="line-height: 115%; font-size: 8pt"><br />
</span>AND</span> <span style="color: blue">type</span> <span style="color: gray">in</span> <span style="color: gray">(</span>N<span style="color: red">'U'</span><span style="color: gray">))<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">DROP</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">TABLE</span> [dbo]<span style="color: gray">.</span>[Altrivacustp_OpportunityNumber]<br />
</span><span style="line-height: 115%; font-size: 8pt"><br />
GO<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">CREATE</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">TABLE</span> Altrivacustp_OpportunityNumber<br />
</span><span style="line-height: 115%; color: gray; font-size: 8pt">(</span><span style="line-height: 115%; font-size: 8pt">objectId <span style="color: blue">Uniqueidentifier</span> <span style="color: gray">NOT</span> <span style="color: gray">NULL,<br />
</span></span><span style="line-height: 115%; font-size: 8pt">ObjectNumber <span style="color: blue">Int</span> <span style="color: blue">IDENTITY</span><span style="color: gray">(</span>1<span style="color: gray">,</span>1<span style="color: gray">),<br />
</span></span><span style="line-height: 115%; font-size: 8pt">Generated <span style="color: blue">bit</span><span style="color: gray">)<br />
<br />
</span></span><span style="line-height: 115%; font-size: 8pt">GO<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">/****** Object:&#160;StoredProcedure [dbo].[Altrivacustp_GenerateUniqueId]&#160;&#160;&#160; Script Date: 05/07/2008 14:27:43 ******/<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">IF</span><span style="line-height: 115%; font-size: 8pt">&#160;<span style="color: gray">EXISTS</span> <span style="color: gray">(</span><span style="color: blue">SELECT</span> <span style="color: gray">*</span> <span style="color: blue">FROM</span> <span style="color: green">sys.objects</span> <span style="color: blue">WHERE</span> <span style="color: fuchsia">object_id</span> <span style="color: gray">=</span> <span style="color: fuchsia">OBJECT_ID</span><span style="color: gray">(</span>N<span style="color: red">'[dbo].[Altrivacustp_GenerateUniqueId]'</span><span style="color: gray">)</span> <span style="color: gray">AND</span> <span style="color: blue">type</span> <span style="color: gray">in</span> <span style="color: gray">(</span>N<span style="color: red">'P'</span><span style="color: gray">,</span> N<span style="color: red">'PC'</span><span style="color: gray">))<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">DROP</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">PROCEDURE</span> [dbo]<span style="color: gray">.</span>[Altrivacustp_GenerateUniqueId]<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt"><br />
/****** Object:&#160;StoredProcedure [dbo].[Altrivacustp_GenerateUniqueId]&#160;&#160;&#160; Script Date: 05/07/2008 13:29:55 ******/<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">SET</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">ANSI_NULLS</span> <span style="color: blue">ON<br />
</span></span><span style="line-height: 115%; font-size: 8pt">GO<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">SET</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">QUOTED_IDENTIFIER</span> <span style="color: blue">ON<br />
</span></span><span style="line-height: 115%; font-size: 8pt">GO<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">CREATE</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">procedure</span> [dbo]<span style="color: gray">.</span>[Altrivacustp_GenerateUniqueId]<span style="color: gray">(</span> @objectID <span style="color: blue">UniqueIdentifier</span> <span style="color: gray">=</span> <span style="color: gray">NULL)</span> <span style="color: blue">as<br />
</span></span><span style="line-height: 115%; color: green; font-size: 8pt">/************ Test the Stored procedure<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">Declare @MyTestGuid UniqueIdentifier<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">SELECT @MyTestGuid = NEWID()<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">EXECUTE Altrivacustp_GenerateUniqueId @MyTestGuid<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">SELECT @MyTestGuid = NULL<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">EXECUTE Altrivacustp_GenerateUniqueId @MyTestGuid<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">SELECT * FROM Altrivacustp_OpportunityNumber<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">**********************/<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">BEGIN<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">set</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: blue">nocount</span> <span style="color: blue">on<br />
<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">Declare</span><span style="line-height: 115%; font-size: 8pt"> @Generated <span style="color: blue">bit<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">SELECT</span><span style="line-height: 115%; font-size: 8pt"> @Generated <span style="color: gray">=</span> 0<br />
<br />
</span><span style="line-height: 115%; color: green; font-size: 8pt">-- Check if @ObjectID is null <br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">if</span><span style="line-height: 115%; font-size: 8pt"> @objectID <span style="color: gray">IS</span> <span style="color: gray">NULL<br />
</span></span><span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">begin<br />
</span></span><span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">select</span> @objectID <span style="color: gray">=</span> <span style="color: fuchsia">NEWID</span><span style="color: gray">(),</span> @Generated <span style="color: gray">=</span> 1&#160;<br />
</span><span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">end</span> <br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">INSERT</span><span style="line-height: 115%; font-size: 8pt"> Altrivacustp_OpportunityNumber<br />
</span><span style="line-height: 115%; font-size: 8pt">&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: gray">(</span>objectId<span style="color: gray">,</span> Generated<span style="color: gray">)<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">VALUES</span><span style="line-height: 115%; font-size: 8pt"> <span style="color: gray">(</span>@objectID<span style="color: gray">,</span> @Generated<span style="color: gray">)<br />
<br />
</span></span><span style="line-height: 115%; color: blue; font-size: 8pt">SELECT</span><span style="line-height: 115%; font-size: 8pt"> ObjectNumber<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">FROM</span><span style="line-height: 115%; font-size: 8pt"> Altrivacustp_OpportunityNumber<br />
</span><span style="line-height: 115%; color: blue; font-size: 8pt">WHERE</span><span style="line-height: 115%; font-size: 8pt"> objectId <span style="color: gray">=</span> @objectID <br />
<span style="line-height: 115%; color: blue; font-size: 8pt">GO</span><br />
</span></div>
<hr />
<p>&#160;</p>
<div>Note that users who are offline and using the CRM for Outlook with Offline Access client will not have a number generated until they go back online and the plug-in is fired during the playback of the playback graph.<br />
<br />
I hope these code snippets give you a good starting place for integrating with other systems when entity GUID primary keys are not ideal, or when a simple integer numbering scheme helps your business processes.</div>
<p>Phil Edry</p>]]></content:encoded><trackback:ping /></item><item><title>Microsoft Dynamics CRM 4.0 Update: Rollup 8</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/21/Microsoft-Dynamics-CRM-4.0-Update:-Rollup-8.aspx</link><author>Justin Mathena</author><guid isPermaLink="false">21</guid><pubDate>Mon, 04 Jan 2010 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft has released update rollup 8 for Dynamics CRM 4.0.&#160; Important notes for this update include:</p>
<ul>
    <li>Requirement to update to rollup 7 prior to installation</li>
    <li>Updates for the 40 supported language packs are contained in the update</li>
</ul>
<p>The knowledge base article regarding the details of Rollup 8 can be found by following this link to&#160;the <a target="_blank" href="http://support.microsoft.com/?kbid=975995">Microsoft Support site</a>.&#160;The update can be downloaded by clicking on this link to the <a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=c53b2916-6b93-4092-bdd3-a394c96ca000">Microsoft Download Center</a>.</p>]]></content:encoded><trackback:ping /></item><item><title>Importing Customizations from one CRM Online Instance to Another CRM Online Instance</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/20/Importing-Customizations-from-one-CRM-Online-Instance-to-Another-CRM-Online-Instance.aspx</link><author>Phil Edry</author><guid isPermaLink="false">20</guid><pubDate>Fri, 11 Dec 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>One issue we’ve run into with two of our Microsoft Dynamics CRM 4.0 Online customers pertains to importing their customizations into a new CRM Online instance. The error you receive when you attempt to import the customizations is “Failure: lead-contact: This attribute map is invalid. A valid attribute map must meet these requirements: - The data type must match. - The length of the target attribute cannot be shorter than the source attribute. - The format should match. - The target attribute must not be used in another mapping. - The source attribute must be visible on the entity form. - The target attribute must be a field a user can enter data into. - Address ID values cannot be mapped.” <br />
<br />
To resolve this issue, you can either figure out which of the requirements in the error message are causing the problem, or if you’re in a hurry, you can remove the XML pertaining to mapping leads to contacts and accounts. WARNING: This may break your mappings from leads to contacts and accounts if you’re not careful. This is also an unsupported route to fixing this issue.<br />
<br />
To remove the XML pertaining to mapping leads, open the zip file with your exported customizations and then extract the customizations.xml file. Open it in your favorite XML editor and do a search on the text “&lt;EntitySource&gt;lead&lt;/EntitySource&gt;”. This will be the first XML element after an “&lt;EntityMap&gt;” element. If “&lt;EntitySource&gt;lead&lt;/EntitySource&gt;” is immediately followed by “&lt;EntitySource&gt;contact&lt;/EntitySource&gt;”, then you know that this “&lt;EntityMap&gt;” maps leads to contacts. Very carefully delete starting at “&lt;EntityMap&gt;” and ending at the very next “&lt;/EntityMap&gt;”. Try the import again. If you get a similar error for accounts instead of contacts, then remove the “&lt;EntityMap&gt;” for lead to account as well.<br />
<br />
The import will now succeed, but there import window may become frozen at 100% complete. If this occurs, wait a few minutes, then close the import window and publish all customizations. Test creating a lead, and then creating a contact and account from that lead to make sure nothing is broken.<br />
<br />
-Phil Edry</p>]]></content:encoded><trackback:ping /></item><item><title>The Power of IFrames: Presenting External Data, Stock Price Graph Example</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/19/The-Power-of-IFrames:-Presenting-External-Data,-Stock-Price-Graph-Example.aspx</link><author>Phil Edry</author><guid isPermaLink="false">19</guid><pubDate>Fri, 16 Oct 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>IFrames are a powerful extension tool within Microsoft Dynamics CRM 4.0. In addition to allowing you to host custom websites, IFrames allow you to present relevant data from external websites within the context of an open entity. As a quick example, this blog post will show how to present historical information regarding a company’s stock price from within an account form. I hope this example will inspire you to find many other ways to present relevant data to users through the use of IFrames.<br />
&#160;</p>
<p>Let’s jump straight into implementing this solution. When we’re done, we’ll have a new tab that has an IFrame reference to Google Finance search on the company’s ticker symbol, or if that isn’t provided, then the company’s name.</p>
<h3>&#160;Step 1: Add a new tab to the account entity.</h3>
<p>In the CRM web client, navigate to Customize Entities &gt;&gt; Account &gt;&gt; Forms and Views &gt;&gt; Form and click Add a Tab. Name the tab as you see fit – we’ll call it “Finance”.</p>
<p><img width="500" height="355" alt="" src="/Portals/0/Blogs/IFrameImg1.jpg" /></p>
<h3>Step 2: Add a Section to the new tab with the default options and then add an IFrame with the following pictured settings entered.</h3>
<p><img width="250" height="369" alt="" src="/Portals/0/Blogs/IFrameImg2.jpg" />&#160;<img width="250" height="369" alt="" src="/Portals/0/Blogs/IFrameImg3.jpg" /><br />
<img alt="" width="287" height="423" src="/Portals/0/Blogs/IFrameImg4.jpg" /></p>
<h3>Step 3: Add JavaScript</h3>
<p>While still on the form, navigate to Form Properties &gt;&gt; OnLoad. Merge the following code into any existing code in the OnLoad event. Be sure to check the “Event is Enabled” check box if it is not already checked.</p>
<table border="1" cellspacing="1" cellpadding="1" width="100%">
    <tbody>
        <tr>
            <td>var sUrl = "about:blank";<br />
            &#160;<br />
            if (crmForm.all.tickersymbol.DataValue != null &amp;&amp; crmForm.all.tickersymbol.DataValue != "")<br />
            {<br />
            &#160;&#160;&#160; sUrl= "http://www.google.com/finance?q=" + crmForm.all.tickersymbol.DataValue;<br />
            }<br />
            else if (crmForm.all.name.DataValue != null &amp;&amp; crmForm.all.name.DataValue != "")<br />
            {<br />
            &#160;&#160;&#160; sUrl= "http://www.google.com/finance?q=" + crmForm.all.name.DataValue;<br />
            }<br />
            crmForm.all.IFRAME_finance.src = sUrl;</td>
        </tr>
    </tbody>
</table>
<p>&#160;<br />
It is a good idea to check for crmForm.FormType to ensure the code only fires when you expect it to, but this is optional. Another optional step would be to add this code to the OnChange event for the Ticker Symbol and Name fields. Also, you could hide the Finance tab whenever the Ticker Symbol field is empty, but note that hiding tabs is technically unsupported in CRM 4.0.<br />
&#160;</p>
<h3>Step 4: Publish<br />
&#160;</h3>
<p>Save and close the form and then click publish.</p>
<p><img width="500" height="299" alt="" src="/Portals/0/Blogs/IFrameImg5.jpg" /></p>
<h3>Conclusion</h3>
<p>That’s it! Now users can get a quick view of the financials for a given company just by switching to the Financials tab. This piece of functionality demoed above is just a taste of what can be done with IFrames. In fact, this functionality is pretty redundant, since users can simple double click the Ticker Symbol on a form and get similar data from MSN Money. The only thing this piece of functionality that this specific customization provides is the ability to search on a company that doesn’t have the Ticker Symbol field filled out, since it uses the name instead. A couple of quick JavaScript changes, and you could easily modify this example to display driving directions from your main office to an account’s primary address using Bing or Google Maps. It is small improvements like these that can give an added boost your customer adoption campaign.<br />
&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>Use Bing Maps with Dynamics CRM 4.0</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/18/Use-Bing-Maps-with-Dynamics-CRM-4.0.aspx</link><author>Tim Dutcher</author><guid isPermaLink="false">18</guid><pubDate>Wed, 30 Sep 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Combining Microsoft Dynamics CRM 4.0 and Bing Maps can help businesses visualize geographic and location-based information quickly and easily. This article provides examples and source code to help you implement this useful mashup.</p>
<p>In the following example, our fictitious client “Amgeen Brake Products” asked us to drop by each of their retail locations in Michigan for a safety inspection. Before getting in her car, our safety inspector opened Dynamics CRM, loaded the Facilities view for the customer, selected the Michigan locations, and clicked the custom Map button to get a print-out of the locations.</p>
<p><img width="500" height="194" alt="" src="/Portals/0/BingMapBlog1.jpg" /></p>
<p>Clicking the Map button invokes a custom ASP.NET application. The application queries CRM for the location (longitude/latitude) of each facility and constructs Jscript code that controls Bing Maps. The resulting map is shown below.</p>
<p><img width="500" height="358" alt="" src="/Portals/0/BingMapBlog2.jpg" /></p>
<p>It looks like our safety inspector has a full day of driving ahead!</p>
<p>Now, let’s jump into technical details for creating the ASP.NET application I mentioned above.</p>
<h2>Application Overview</h2>
<p>The Visual Studio .NET 2005 application structure is shown below. The application is deployed as a typical CRM ISV application, which means that it is deployed into a subfolder under the CRM website ISV folder.&#160; (Note: The solution uses the Web Deployment Projects add-in from Microsoft to produce a fixed .NET assembly name.)</p>
<p><img alt="" width="267" height="191" src="/Portals/0/BingMapBlog4.jpg" /></p>
<p>The file that is called from CRM (by way of a custom ISV.Config button) is “MapSelectedFacilities.aspx”. The custom button is added to the Facility grid’s menubar with the following ISV.Config entry:</p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&lt;Grid&gt;<br />
&lt;MenuBar&gt;<br />
&#160; &lt;Buttons&gt;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;Button Icon="/_imgs/ico_18_debug.gif" Url="/isv/altriva/BingMaps/MapSelectedFacilities.aspx" WinMode="2"&gt;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;Titles&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;Title LCID="1033" Text="Map" /&gt;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;/Titles&gt;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;ToolTips&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160;&#160;&#160; &lt;ToolTip LCID="1033" Text="Map the selected Facility records" /&gt;&#160;&#160;&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;/ToolTips&gt;&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;/Button&gt;&#160; <br />
&#160; &lt;/Buttons&gt;<br />
&#160; &lt;/MenuBar&gt;<br />
&lt;/Grid&gt;</span></span></p>
<h3>Determining Selected Rows in a CRM Grid</h3>
<p>In order to map only the selected facilities, it’s necessary to get the ID of each of the selected facilities in the CRM grid and pass the collection to the ASP.NET application. The function “listselecteditems” in the ASPX page (see below) provides this functionality.&#160; (Thanks to David Fronk at Dynamic Methods for posting the hidden field technique that I ended up using in this application.)</p>
<p>The HTML for MapSelectedFacilities.aspx and the code-behind C# class is provided below.</p>
<h3>MapSelectedFacilities.aspx</h3>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&lt;%@ Page Language="C#" AutoEventWireup="true"&#160; CodeFile="MapSelectedFacilities.aspx.cs" Inherits="MapSelectedFacilities" %&gt;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br />
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;<br />
&lt;head runat="server"&gt;<br />
&#160;&#160;&#160; &lt;title&gt;Bing Map&lt;/title&gt;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160; &lt;script type="text/javascript"&gt;<br />
&#160;&#160;&#160; function listselecteditems()<br />
&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; var hiddenfield = document.getElementById("HiddenField_SelectedGUIDs");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; var sGUIDValues = "";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; var selectedValues;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (window.dialogArguments)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; selectedValues = new Array(window.dialogArguments.length - 1);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; else<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; selectedValues = window.dialogArguments;<br />
&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (selectedValues != null)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (i = 0; i &lt; selectedValues.length; i++)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sGUIDValues += selectedValues[i] + "\n";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var hidden = sGUIDValues;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; form1.HiddenField_SelectedGUIDs.value = hidden;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; form1.submit();<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; else<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert("Please select one or more facility records to map.");&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; }&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body onload="listselecteditems()"&gt;&#160;&#160;&#160;&#160;<br />
&#160;&#160;&#160; &lt;form id="form1" runat="server"&gt;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;input id="HiddenField_SelectedGUIDs" type="hidden" runat="server" /&gt;&#160;&#160;&#160; <br />
&#160;&#160;&#160; &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</span></span></p>
<p>When CRM invokes MapSelectedFacilities.aspx, it provides the selected facility IDs in the dialogArguments window property. Those values are stored in the hidden HTML object “HiddenField_SelectedGUIDs”.</p>
<h3>MapSelectedFacilities.aspx.cs</h3>
<p><span style="font-size: x-small"><span style="font-family: Courier New">using System;<br />
using System.Data;<br />
using System.Configuration;<br />
using System.Web;<br />
using System.Web.Security;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
using System.Web.UI.WebControls.WebParts;<br />
using System.Web.UI.HtmlControls;<br />
using Microsoft.Crm.Sdk;<br />
using Microsoft.Crm.Sdk.Query;<br />
using Microsoft.Crm.SdkTypeProxy;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">public partial class MapSelectedFacilities : System.Web.UI.Page<br />
{<br />
&#160;&#160;&#160; AccountFacilities _accountFacilities;<br />
&#160;&#160;&#160; protected void Page_Load(object sender, EventArgs e)<br />
&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (this.IsPostBack)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string crmOrgName = "Altriva";</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (HiddenField_SelectedGUIDs.Value != string.Empty)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Get the list of selected Facility records in the CRM grid view<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string rawFacilityGuidList = HiddenField_SelectedGUIDs.Value.ToString();<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; rawFacilityGuidList = rawFacilityGuidList.TrimEnd();<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; rawFacilityGuidList = rawFacilityGuidList.Replace("{", "").Replace("}", "");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string[] arrFacilityGuidsStr = rawFacilityGuidList.Split(new char[] { '\n' });</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (new CrmImpersonator())<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CrmDataRetriever crmDataRetriever = new CrmDataRetriever(crmOrgName);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _accountFacilities = crmDataRetriever.GetFacilityLocationDetails(arrFacilityGuidsStr);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Server.Transfer("~/MapSelectedFacilitiesPost.aspx", true);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160; }<br />
&#160;&#160;&#160; public AccountFacilities FacilityDetails<br />
&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; get<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return this._accountFacilities;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160; }<br />
}</span></span></p>
<p>When the code-behind is executed, it reads the list of GUIDs, parses them into an array, and then queries CRM for the longitude and latitude for each of the facilities. The custom method GetFacilityLocationDetails is in a class that is responsible for querying CRM for facility details. Since there are several examples of querying CRM data in the CRM SDK I am not providing the source code for the CrmDataRetriever class – it is simply a class that’s responsible for retrieving and storing (as class properties) facility details.</p>
<p>For purposes of “separation of responsibility” in the application design, I chose to divide the work of collecting facility details and rendering the Bing Map into two ASPX pages. That explains the use of Server.Transfer in the code-behind provided above.</p>
<h3>Rendering the Bing Map</h3>
<p>As mentioned above, the code-behind for MapSelectedFacilities.aspx passes control to MapSelectedFacilitiesPost.aspx. This second page generates the Jscript code to render the Bing Map.</p>
<p>The HTML for MapSelectedFacilitiesPost.aspx and the code-behind is provided below.</p>
<h3>MapSelectedFacilitiesPost.aspx</h3>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="MapSelectedFacilitiesPost.aspx.cs" Inherits="MapSelectedFacilitiesPost" %&gt;<br />
&lt;%@ PreviousPageType VirtualPath="~/MapSelectedFacilities.aspx" %&gt;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br />
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;<br />
&lt;head runat="server"&gt;&#160;&#160;&#160; <br />
&#160; &lt;title&gt;Facilities&lt;/title&gt;&#160;&#160;&#160; <br />
&#160; &lt;script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"&gt;<br />
&#160; &lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body onload="LoadMap()" onunload="UnloadMap()"&gt;&#160;&#160;&#160; <br />
&#160; &lt;form id="form1" runat="server"&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160; &lt;div id='mapDiv' style="position:relative; width:800px; height:600px;" runat="server"&gt;<br />
&#160; &lt;/div&gt;&#160;&#160;&#160; <br />
&#160; &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</span></span></p>
<p>You’ll see that the onload event of the HTML body calls a function named “LoadMap”. That function, along with UnloadMap, is generated in the page’s code-behind.</p>
<h3>MapSelectedFacilitiesPost.aspx.cs</h3>
<p><span style="font-size: x-small"><span style="font-family: Courier New">using System;<br />
using System.Data;<br />
using System.Configuration;<br />
using System.Collections;<br />
using System.Web;<br />
using System.Web.Security;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
using System.Web.UI.WebControls.WebParts;<br />
using System.Web.UI.HtmlControls;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">public partial class MapSelectedFacilitiesPost : System.Web.UI.Page<br />
{<br />
&#160;&#160;&#160; protected void Page_Load(object sender, EventArgs e)<br />
&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; GenerateClientSideMapCode(PreviousPage.FacilityDetails);<br />
&#160;&#160;&#160; }<br />
&#160;&#160;&#160; private void GenerateClientSideMapCode(AccountFacilities accountFacilities)<br />
&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; ClientScriptManager csm = Page.ClientScript;</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">string code = @"<br />
&lt;script type='text/javascript'&gt;<br />
&#160;var myMap = null;<br />
&#160;function LoadMap()<br />
&#160;{<br />
&#160;&#160;&#160; myMap = new VEMap('mapDiv');<br />
&#160;&#160;&#160; myMap.LoadMap();<br />
&#160;&#160;&#160; AddPushpinShapes();<br />
&#160;}</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;function UnloadMap()<br />
&#160;{<br />
&#160;&#160;&#160; if (myMap != null) {<br />
&#160;&#160;&#160;&#160;&#160;&#160; myMap.Dispose();<br />
&#160;&#160;&#160; }<br />
&#160;}<br />
";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Render the JavaScript code that adds pushpins to the map.<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; int mapShapeCounter = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; string pushpinCode = "\n\nfunction AddPushpinShapes()\n{";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "var pushpinCounter = 0;" + "\n";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; foreach (AccountFacilities.AccountFacilitiesRow dr in accountFacilities._AccountFacilities)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!dr.IsFacilityLatitudeNull() &amp;&amp; !dr.IsFacilityLongitudeNull() &amp;&amp; dr.FacilityLatitude != "0" &amp;&amp; dr.FacilityLongitude != "0")<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mapShapeCounter++;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "var veLatLong" + mapShapeCounter + " = new VELatLong(" + dr.FacilityLatitude + "," + dr.FacilityLongitude + ");";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "var veShape" + mapShapeCounter + " = new VEShape(VEShapeType.Pushpin, veLatLong" + mapShapeCounter + ");";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "myMap.AddShape(veShape" + mapShapeCounter + ");";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "pushpinCounter++;" + "\n";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushpinCode += "\n" + "if (pushpinCounter &gt; 0) { myMap.SetCenterAndZoom(veLatLong1, 7); }\n}";<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; code += pushpinCode;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; code += "\n\n&lt;/script&gt;";</span></span></p>
<p><span style="font-size: x-small"><span style="font-family: Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; csm.RegisterClientScriptBlock(this.GetType(), "map", code);<br />
&#160;&#160;&#160; }<br />
}<br />
</span></span></p>
<p><br />
The code-behind generates the Jscript code that creates the Bing Map instance (see “new VEMap”), plots the pushpins, and then registered the Jscript code with the page so that it will execute once the page loads. The mapping process begins with the call to the LoadMap function.</p>
<h3>A Second Example</h3>
<p>The screen shown below demonstrates another way of integrating Bing Maps into Dynamics CRM. In this example, the Bing Maps screen appears in an IFRAME within the CRM UI. The code needed to implement this functionality is essentially the same as provided in this article. The difference is that, for this implementation, all facilities for the account are mapped rather than only the selected facilities.</p>
<p><img width="500" height="344" alt="" src="/Portals/0/BingMapBlog3.jpg" /></p>
<h2>Summary</h2>
<p>With a small amount of ASP.NET and Jscript code, it’s possible to add significant new capabilities to Dynamics CRM. This blog post demonstrated how using Bing Maps with CRM data can help service personnel plan for road travel. Bing Maps have hundreds of other uses as well. Some of the more popular applications include geography-based sales analysis, GPS-based tracking of personnel and vehicles, and for strategic planning of business opportunities.</p>
<h3>Bing Maps Licensing</h3>
<p>Please visit the <a target="_blank" href="http://www.microsoft.com/maps/product/licensing.aspx">Licensing Bing Maps for Enterprise </a>page for details regarding the commercial use of Bing Maps.</p>]]></content:encoded><trackback:ping /></item><item><title>CRM to SharePoint Site Creation and Clients List Integration</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/17/CRM-to-SharePoint-Site-Creation-and-Clients-List-Integration.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">17</guid><pubDate>Fri, 18 Sep 2009 00:00:00 GMT</pubDate><category>CRM</category><category>SharePoint</category><content:encoded><![CDATA[<p>Whenever we’ve added extensions or integrations to our internal CRM and SharePoint implementations, we continually focus on developing these tools so they can be easily deployed for our clients as well.&#160;Therefore, in addition to making our own enterprise tools more useful, we’re able to deliver increased value for our clients. &#160;The integration between MS CRM 4.0 and SharePoint 2007 enables the creation of client and project sites in SharePoint with a simple CRM checkbox.</p>
<div style="margin: 0in 0in 10pt">This integration solution aimed at automating the creation of SharePoint sites directly from CRM to streamline our sales and project processes, as well as provide a consistent method for representing our customer data. &#160;Customer records each have their own corresponding SharePoint site with sub-sites created for each project.&#160;&#160;In CRM, Altriva customers each have their own Account records and each project is represented by an Opportunity record.</div>
<div style="margin: 0in 0in 10pt"><img alt="CRM SharePoint Integration screenshot 1" width="500" height="265" src="/Portals/0/20090918crmsp1.jpg" /></div>
<div style="margin: 0in 0in 10pt">With our integration, SharePoint client sites are auto-generated by checking the “Create Site” check box and saving the account. This triggers a plug-in that calls a custom-built web service, which in turn creates the SharePoint site via the SharePoint API. The web service returns the URL for the new site and the plug-in updates a field on the account with the site URL. An IFrame on a separate tab uses this URL and allows users to fully access the SharePoint site from within CRM.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="376" alt="" src="/Portals/0/20090918crmsp2.jpg" /></div>
<div style="margin: 0in 0in 10pt">The same basic integration was implemented for opportunities, except that the plug-in retrieved the URL of the parent account’s SharePoint site and used it as the parent site of the opportunity’s SharePoint project site.</div>
<div style="margin: 0in 0in 10pt">The functionality described so far has been a big win for our sales and project management processes since SharePoint sites are easy to create and access without ever leaving CRM. To facilitate navigating among the growing number of client sites within SharePoint we implemented a SharePoint list called “Clients” that stores customer names and their respective SharePoint site URLs. This list is kept in sync with CRM account records through a plug-in registered on create and update of CRM account records that calls the SharePoint web services to update list members. We then built a web part on our welcome page that linked to each client site by client name to provide a fast way to access a given client site.&#160;We have also built custom SharePoint web parts that use the “Clients” list to keep certain documents in one central location (e.g., Contracts, Invoices) but display them within each client site.</div>
<div style="margin: 0in 0in 10pt">With these integrations Altriva has an easy way to build and maintain a full view of our clients by leveraging SharePoint to add document management to our CRM client vision. Best of all, we built this integration to be reusable for interested clients.</div>]]></content:encoded><trackback:ping /></item><item><title>Allow Multiple Users to Sync the Same Contact to Outlook Effortlessly with Microsoft CRM</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/16/Allow-Multiple-Users-to-Sync-the-Same-Contact-to-Outlook-Effortlessly-with-Microsoft-CRM.aspx</link><author>Phil Edry</author><guid isPermaLink="false">16</guid><pubDate>Tue, 25 Aug 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft Dynamics CRM 4.0 offers powerful functionality to synchronize data between CRM and your local Outlook.&#160;Most companies have certain contacts that many users interact with and want in their Outlook but Microsoft CRM does not give you an easy way to pick the contacts you want to bring down to your Outlook.&#160;This can be especially useful to users who sync their smart phones, blackberries, etc. to Outlook or Exchange because they can now access their CRM contacts through their phones address book.&#160;&#160;Here at Altriva, one of the many “quick business facilitation configurations” we have in our toolkit extends this functionality to allow users (and multiple users per contact) to easily add and remove contacts synchronized to their Outlook.&#160;This allows multiple users to sync the same contact to Outlook effortlessly and allows users to decide which contacts they bring to their Outlook.&#160;&#160;&#160;&#160;</p>
<div style="margin: 0in 0in 10pt">By Default, CRM 4.0 will sync contacts that a user owns in CRM to their Outlook. Users can modify their Local Data Groups to refine the rules that determine which contacts sync to their Outlook. &#160;However, it is not immediately clear how you could easily choose individual contacts or groups of loosely-related contacts to sync with your Outlook without creating a large number of local data rules.&#160;An easy way to do this is to use Microsoft Dynamics CRM’s ability to create custom entities and relationships to build a new entity that allow users to designate contacts or companies (all contacts at a company) to synchronize down to their outlook contacts.&#160;</div>
<div style="margin: 0in 0in 10pt">The concept is simple. Use one user owned custom entity and N:1 relationships from contact and account to the customer entity.&#160;&#160; Then we modify each user’s local data groups to query contacts based on the related entity.&#160;We would also build views and workflows that make it easy for the user to select which contacts they want synchronized to Outlook.&#160;This could include automatically generating the “Sync User” entity for a contact record when a user creates the contact record so it is tagged to come down to Outlook for the user that created it.&#160;This would also include a manual workflow rule so from any list of contacts the user could easily select one or multiple contacts they want synchronized.</div>
<div style="margin: 0in 0in 10pt">This solution is very handy in many business situations:</div>
<ul>
    <li>
    <div>It does not force users to always bring down all contacts that they own in CRM.</div>
    </li>
    <li>
    <div>It allows multiple users to easily synchronize the same contact record to their Outlook contacts.</div>
    </li>
    <li>
    <div>It allows users to easily select the subset of contacts they want to sync to Outlook by providing a quick way for marking or unmarking a contact to be synchronized.</div>
    </li>
    <li>
    <div>It allows other users in the organization the option to view who else is synchronizing a contact into Outlook (optional).</div>
    </li>
    <li>
    <div>It allows an administrative assistant to set up which contacts sync to their boss’ Outlook contacts, which makes it so the higher level users just have the data they need when they need it (optional).</div>
    </li>
</ul>
<p>Another great benefit from this solution is that it requires absolutely no custom coding. The solution completely relies on the functionality of Microsoft Dynamics CRM by creating the custom entities, local data filters, relationships, automatic workflows, manual workflows and new views to manage what contacts users want in their Outlook contacts.</p>
<div style="margin: 0in 0in 10pt">Below is a subset of the overall solution that outlines the steps for the basics of setting up multiple user contact synchronization at the contact level.</div>
<div style="margin: 0in 0in 10pt"><b><u>Solution Subset</u></b></div>
<div style="margin: 0in 0in 10pt">This solution subset described below will be doing the following:</div>
<ol>
    <li>Create a user-owned custom entity called “Sync User” with an N-1 relationship to contacts,</li>
    <li>Create a workflow that will run against contacts and create a Sync User instance relating the current user to the contact,</li>
    <li>Modify the Local Data Groups for each CRM for Outlook client to sync contacts where the related user equals the current user,</li>
    <li>Train users on how to run On Demand workflows to sync contacts.</li>
</ol>
<div style="margin: 0in 0in 10pt">This solution subset does not include the following pieces:</div>
<ol>
    <li>Building automatic workflows to automatically set users up to synchronize contacts,</li>
    <li>Configuring a Sync User view to easily review and remove contacts from being synchronized,</li>
    <li>The ability to sync all contacts at a company, including contacts added in the future,</li>
    <li>System views to allow users to see which contacts are being synchronized,</li>
    <li>Security role setup.</li>
</ol>
<div style="margin: 0in 0in 10pt"><b><u>Subset Step-by-Step Implementation Guide</u></b></div>
<div style="margin: 0in 0in 10pt">Whenever making changes to CRM customizations, we strongly encourage you to do it in a dev or test system before deploying to production, as well as backing up all customizations and the CRM databases in each environment before beginning customization.</div>
<div style="margin: 0in 0in 10pt"><b>Step 1: Create the Sync User Entity</b></div>
<div style="margin: 0in 0in 10pt">Open the CRM web client and navigate to the Customize Entities menu while logged in as a user with customizer permissions. Click New to create a new entity.</div>
<div style="margin: 0in 0in 10pt"><img alt="" width="437" height="138" src="/Portals/0/Sync Users Image 1.jpg" /></div>
<div style="margin: 0in 0in 10pt">Make sure both tabs look like the following two images <i><u>before clicking save</u></i>. <b>Important:</b> Many of the fields on the new entity form cannot be edited after saving. For example, be sure to extend the primary attribute’s length to 160 before saving.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="406" alt="" src="/Portals/0/Sync Users Image 2.jpg" /></div>
<div style="margin: 0in 0in 10pt"><img width="500" height="344" alt="" src="/Portals/0/Sync Users Image 3.jpg" /></div>
<div style="margin: 0in 0in 10pt">Click Save. Navigate to N:1 Relationships and create the following relationship to contact.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="328" alt="" src="/Portals/0/Sync Users Image 4.jpg" /></div>
<div style="margin: 0in 0in 10pt">Add a mapping to this relationship to map the contacts full name to the
<prefix></prefix>
_contact_fullname attribute on the Sync User entity. Save and close the relationship. (This step is optional).</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="168" alt="" src="/Portals/0/Sync Users Image 5.jpg" /></div>
<div style="margin: 0in 0in 10pt">Navigate to attributes and rename the display name of the ownerid attribute from “Owner” to “Sync User”. Then save and close the attribute.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="276" alt="" src="/Portals/0/Sync Users Image 6.jpg" /></div>
<div style="margin: 0in 0in 10pt">Navigate to Forms and Views and open the Form for the Sync User entity. Add and remove fields as appropriate until the form looks a pictured below.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="197" alt="" src="/Portals/0/Sync Users Image 7.jpg" /></div>
<div style="margin: 0in 0in 10pt">Save the form, save and close the entity, and then publish all entities, or if that isn’t an option, publish the Sync User entity, the contact entity, and the system user entity.</div>
<div style="margin: 0in 0in 10pt"><b>Step 2: Create the “Set Contact to Sync to Outlook” workflow</b></div>
<div style="margin: 0in 0in 10pt">Navigate to Workflows in the Settings section of CRM. Click the New button to create a new workflow.</div>
<div style="margin: 0in 0in 10pt">Name the workflow, set the scope, and check “On Demand”. If you would like contacts to automatically sync to whomever created it, also check “Record is created”.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="267" alt="" src="/Portals/0/Sync Users Image 8.jpg" /></div>
<div style="margin: 0in 0in 10pt">Click Add Step &gt;&gt; Create Record. Select Sync User Entity. Open the properties and configure the two tabs to appear as pictured below.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="164" alt="" src="/Portals/0/Sync Users Image 9.jpg" /></div>
<div style="margin: 0in 0in 10pt"><img width="500" height="164" alt="" src="/Portals/0/Sync Users Image 10.jpg" /></div>
<div style="margin: 0in 0in 10pt">Publish the workflow.</div>
<div style="margin: 0in 0in 10pt"><b>Step 3: Modify Local Data Groups</b></div>
<div style="margin: 0in 0in 10pt">The following needs to be done one each workstation you intend to support the Sync User entity.</div>
<div style="margin: 0in 0in 10pt">Open CRM for Outlook and navigate to CRM &gt;&gt; Modify Local Data Groups.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="377" alt="" src="/Portals/0/Sync Users Image 11.jpg" /></div>
<div style="margin: 0in 0in 10pt">Click New. Configure the Local Data Group rule to look as pictured below.</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="170" alt="" src="/Portals/0/Sync Users Image 12.jpg" /></div>
<div style="margin: 0in 0in 10pt">Save and close Local Data Groups.</div>
<div style="margin: 0in 0in 10pt"><b>Step 4: Training users to use Sync Users</b></div>
<div style="margin: 0in 0in 10pt">There are two ways to specify which contacts to sync to outlook.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in"><span>1.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Individual Contact Selection.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 10pt 1in"><span>a.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>With a contact form open, click “Run Workflow” (Note: Users need appropriate permissions for this button to show up)</div>
<div style="margin: 0in 0in 10pt"><img width="500" height="213" alt="" src="/Portals/0/Sync Users Image 13.jpg" /></div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 1in"><span>b.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160; </span></span>Select “Set Contact to Sync to Outlook” and click OK. This contact will sync the next time Outlook Synchronizes with CRM.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in"><span>2.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Multiple Contact Selection</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 1in"><span>a.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>From within a view of contacts (either a saved view or an Advanced Find result set), select the contacts you want to sync. Then click “Run Workflow”</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 1in"><span>b.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160; </span></span>Select “Set Contact to Sync to Outlook” and click OK. These contacts will sync the next time Outlook Synchronizes with CRM.</div>
<div style="margin: 0in 0in 10pt 1in">&#160;</div>
<div style="margin: 0in 0in 10pt">Thanks for reading,</div>
<div style="text-indent: -0.25in; margin: 0in 0in 10pt 0.5in"><span>-<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Hoss Hostetler and Phil Edry</div>
<p>&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>Adding a Custom Calendar to the CRM UI</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/15/Adding-a-Custom-Calendar-to-the-CRM-UI.aspx</link><author>Tim Dutcher</author><guid isPermaLink="false">15</guid><pubDate>Wed, 29 Jul 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Adding a custom event calendar to Dynamics CRM 4.0 can help team members stay in synch on events, milestones, and deadlines and can help provide visibility into major events.&#160;Although CRM 4.0 provides a calendar view in the product, a custom calendar is often needed to show events that are not time-based and are not linked to appointments or service activities.</p>
<p>This blog post provides examples of how various industries can utilize a custom calendar and provides technical details for how a custom calendar can be implemented.</p>
<p>One example of the potential use of a custom calendar is in the real estate industry. If the major milestones of a real estate transaction (appraisal, inspection, closing, possession, etc.) are stored as dates on the Opportunity record, then those dates can be shown on a calendar along with the client’s name and milestone description. This can help keep office team members, clients, and third-parties informed of major milestones for a real estate office’s transactions.</p>
<p>Another industry or team that can benefit from a custom calendar within Dynamics CRM is one that manages deadlines for tradeshow participation. Having been involved with several tradeshows in my own career I know that it takes a tremendous amount of coordination effort to make sure everything comes together.</p>
<p><b>Demonstration</b></p>
<p>In the following example, I created a custom entity named “Tradeshow” to track the various shows that a company could participate in and the related deadlines.</p>
<p><img alt="Tradeshow custom entity" width="500" height="232" src="/Portals/0/blog_tradeshowentity.png" /></p>
<div style="margin: 0in 0in 0pt">Although it’s possible to list the tradeshows and deadlines in a view or in a custom report, using a calendar view is often beneficial to show overlaps in deadlines and to better visualize upcoming events.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt">A calendar view showing “MS Gold Partner Expo” and another trade show might appear like this:</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt"><img width="500" height="265" alt="" src="/Portals/0/blog_customcalendar.png" /></div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt">Each entry in this calendar is a hyperlink that will display the Tradeshow record when clicked. Also, the calendar could be extended to show a checkmark image when the milestone or deadline is completed.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt"><b>Choices for Implementing a Custom Calendar</b></div>
<div style="margin: 0in 0in 0pt">There are several approaches you can take to populate and display a calendar within Dynamics CRM.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt"><i>Build It</i></div>
<div style="margin: 0in 0in 0pt">Depending on your company’s technical expertise, you might choose to build the calendar from scratch as an ASP.NET application, as a SQL Reporting Services report, or entirely in JavaScript.&#160;For instance, you might decide that the look and behavior of the <a target="_blank" href="http://www.microsoft.com/events/webcasts/calendar/monthview.aspx">Microsoft Webcast Calendar</a> is exactly what you need so you fire up Visual Studio and start in on the application.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt"><i>Start with Open Source</i></div>
<div style="margin: 0in 0in 0pt">Rather than start from scratch, though, it’s often best to visit Open Source sites such as CodePlex, SourceForge, or The Code Project to obtain the source code for calendars that might provide most of the functionality that you need. &#160;Here are some Open Source options:</div>
<ul>
    <li><a target="_blank" href="http://www.codeproject.com/KB/aspnet/EventCalendar.aspx">Event Calendar</a>&#160;&#160;(The Code Project)</li>
    <li><a target="_blank" href="http://sourceforge.net/projects/daypilot/">DayPilot</a> (SourceForge)</li>
</ul>
<div style="margin: 0in 0in 0pt"><i>License a Component</i></div>
<div style="margin: 0in 0in 0pt">Another approach is to purchase a license to a programmable pre-built component. There are numerous components available including:</div>
<ul>
    <li><a target="_blank" href="http://www.daypilot.org/demo/Calendar/"><span>DayPilot</span></a> (Full version)</li>
    <li><a target="_blank" href="http://www.dundas.com/Products/Calendar/RS/index.aspx"><span>Dundas Calendar</span></a></li>
    <li><a target="_blank" href="http://www.scriptcalendar.com/scrptcal/default.aspx"><span>ScriptCalendar</span></a></li>
    <li><a target="_blank" href="http://www.infragistics.com/dotnet/netadvantage/aspnet/webschedule.aspx#Overview"><span>Infragistics WebSchedule</span></a></li>
    <li><a target="_blank" href="http://www.quickwebsoft.com/"><span>Quickwebsoft EventCalendar</span></a></li>
</ul>
<div style="margin: 0in 0in 0pt"><i>Mashup</i></div>
<div style="margin: 0in 0in 0pt">Rather than deploy a component to your web server it’s also possible to incorporate a web-based calendar within Dynamics CRM. You can simply add a link in your CRM instance’s SiteMap or ISV.Config settings to point to an online calendar. Many online calendars exist including the following:</div>
<ul>
    <li><a target="_blank" href="http://code.google.com/apis/gdata/client-cs.html"><span>Google Calendar&#160;</span></a>&#160;</li>
    <li><a target="_blank" href="http://www.microsoft.com/windows/windows-vista/features/calendar.aspx"><span>Windows Live Calendar</span></a> (Note: At the time of this blog post, Microsoft had not yet released an API/SDK for this calendar. However, the word is that it will be programmable soon.)</li>
    <li><a target="_blank" href="http://30boxes.com/welcome.php"><span>30Boxes Calendar</span></a></li>
</ul>
<div style="margin: 0in 0in 0pt"><b>Implementing an Events Calendar with ScriptCalendar</b></div>
<div style="margin: 0in 0in 0pt">I built the Tradeshow calendar (see above) using the JavaScript-based <a target="_blank" href="http://www.scriptcalendar.com/scrptcal/default.aspx">ScriptCalendar</a> component ($69 server license). The component’s author provides a demonstration copy of the software with the limitation of only showing the first half of the month’s events.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt">Here are the steps I took to implement the ScriptCalendar component for the Tradeshow example (on a Dynamics CRM 4.0 demo VPC):</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in"><span>1.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Download the ScriptCalendar application and extract the files to C:\Program Files\Microsoft Dynamics CRM\CRMWeb\ISV\Altriva\TradeShowCalendar\.</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in"><span>2.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Load Visual Studio 2005 and start a new Web Site application. This application queries Dynamics CRM to retrieve event details and writes the event information to an XML file that ScriptCalendar utilizes to display events.&#160;(Note: On the ScriptCalendar website you will find a sample ASP.NET C# application the demonstrates how to programmatically create an XML file that ScriptCalendar can utilize to populate the calendar.)</div>
<div style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in"><span>3.<span style="font: 7pt 'Times New Roman'">&#160;&#160;&#160;&#160;&#160;&#160; </span></span>Update the Dynamics CRM SiteMap to provide a link to the custom calendar. The URL should point to the default.aspx file you created in Visual Studio. Once the custom ASP.NET applications queries CRM and prepares the XML file for ScriptCalendar, your code should Response.Redirect to the calendar’s main HTML file (scrptcal.htm).</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt">With ScriptCalendar, then, the implementation of a custom calendar is relatively simple. The only custom development needed is the code to query CRM and build the events XML file. However, you may be able to avoid custom code altogether if you&#160;schedule a SQL process (e.g., SQL Server Integration Services) to query CRM periodically and refresh the ScriptCalendar XML file. That approach might suffice if up-to-the-minute event information is not a requirement.</div>
<div style="margin: 0in 0in 0pt">&#160;</div>
<div style="margin: 0in 0in 0pt"><b>Other Uses for a Custom Calendar</b></div>
<div style="margin: 0in 0in 0pt">Other examples of industries or teams that can use Dynamics CRM combined with a custom calendar to better manage events, milestones, and deadlines include the following:</div>
<ul>
    <li>Project managers</li>
    <li>Information technology firms</li>
    <li>Sales teams</li>
    <li>Legal firms</li>
    <li>General contractors</li>
    <li>Recruitment firms</li>
    <li>Financial advisors</li>
</ul>
<div style="margin: 0in 0in 0pt">Essentially, any company or group that coordinates or tracks milestones, events, or deadlines can make use of a standard or custom entity in Dynamics CRM to store important dates and a custom calendar to better visualize the information.</div>]]></content:encoded><trackback:ping /></item><item><title>Multiple "Owners" in CRM</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/14/Multiple-"Owners"-in-CRM.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">14</guid><pubDate>Fri, 10 Jul 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: ">There are many instances where businesses want multiple “owners” of something within CRM.<span style="mso-spacerun: yes">&#160; </span>Having multiple users own something comes in many different forms when related to CRM. Examples include team selling using CRM Opportunity records, team support using Cases, and Tasks assigned to a group. Microsoft CRM is constructed such that one user is the “owner” of each record within CRM.<span style="mso-spacerun: yes">&#160; </span>Can we alter the system to modify this ownership?</span></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Depending on the functionality you are looking to support, assigning multiple owners to a record can be accomplished many different ways in CRM.<span style="mso-spacerun: yes">&#160; </span>The question to start with is what functionality your business needs to support with multiple “owners” of something within in CRM.<span style="mso-spacerun: yes">&#160; </span>Are you trying to designate multiple individuals who are responsible for a record or task for reporting purposes?<span style="mso-spacerun: yes">&#160; </span>Are you trying to allow users to sync sets of data offline or contacts to Outlook without creating a separate local data filter for each account, opportunity or contact they want offline?<span style="mso-spacerun: yes">&#160; </span>Are you trying to restrict and grant access for people to be able to see and update records?<span style="mso-spacerun: yes">&#160; </span>Are you trying to provide users with an easy way to view the records for which they are a partial “owner”?<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Today we will be looking into one of these scenarios: the need to restrict access to records based on the multiple owners of the record. <o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">For this example, let’s assume we have a very restrictive access within our CRM system which requires only the owners of an Opportunity the ability to edit it.<span style="mso-spacerun: yes">&#160; </span>This would work easily if the opportunity only had one owner but in this case each opportunity is handled by three people.<span style="mso-spacerun: yes">&#160; </span>These three people are the field salesperson, the field salesperson inside sales counterpart and an assigned technical support staff who is assigned per opportunity.<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Now that we have defined what functionality we want we can begin designing how to accomplish it within CRM.<span style="mso-spacerun: yes">&#160; </span>To do this we first need to understand how a few things work in CRM by default and then begin to build on top of that based on the functionality we are looking for.<strong><font size="5"><font color="#365f91"><font face="Cambria"><o:p></o:p></font></font></font></strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><strong>Microsoft CRM Security Structure</strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">How does Security work within Microsoft CRM? How does owning a record in CRM relate to security?<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Microsoft CRM by default has records in CRM that are either owned at the Organization, Business Unit or the User level.<span style="mso-spacerun: yes">&#160; </span>You can only create new entities that are either Organization or User owned.<span style="mso-spacerun: yes">&#160; </span>The ownership of records within Microsoft CRM is directly linked to security and granting or denying access to records.<span style="mso-spacerun: yes">&#160; </span><o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">We cannot change the default ownership structure within Microsoft CRM.<span style="mso-spacerun: yes">&#160; </span>All records in Microsoft CRM will either be owned by the Organization or a Business Unit or a single User.<span style="mso-spacerun: yes">&#160; </span>That is not a customizable option for entities in the system or new entities we create.<span style="mso-spacerun: yes">&#160; </span>This means that we will have to build a new “ownership” structure that will facilitate our requested functionality.<span style="mso-spacerun: yes">&#160;&#160; </span><o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Basically, record access can be granted at 4 levels:<o:p></o:p></p>
<ul>
    <li>Organization (You can perform the action no matter where you or the record exists)<o:p></o:p></li>
    <li>Deep or Parent/Child Business Unit (You can Perform the action as long as the record is in your business unit or a business unit underneath your business unit in the hierarchy)<o:p></o:p></li>
    <li>Business Unit (You can perform the action as long as the record is in your business unit)<o:p></o:p></li>
    <li>User Owned (You can only perform the action as long as you are the owner of the record)</li>
</ul>
<p class="MsoListParagraphCxSpLast" style="text-align: justify; text-indent: -0.25in; margin: 0in 0in 10pt 0.5in; mso-list: l0 level1 lfo1"><o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Microsoft CRM also provides the ability for users to grant access to a record they own to other users. This is called sharing.<span style="mso-spacerun: yes">&#160; </span>Users can either share records to specific users or create a team within CRM that contains multiple users and share to the team thereby giving everyone in the team the access that they just granted to the team. <o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><strong>Design Options</strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Now that we have an understanding of how Microsoft CRM uses record ownership and we have our functionality requirements we can begin to design a system that could accomplish the functionality we are looking for.<span style="mso-spacerun: yes">&#160;</span></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><em>Manual Process using Sharing</em></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">The first option is to use the built-in security capability, along with a manual process, to provide this functionality to users.<span style="mso-spacerun: yes">&#160; </span><o:p></o:p></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: ">To do this, you would simply create a security role that only allows users to see and edit opportunities for which they are the owner. </span></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: "><img width="500" height="18" alt="" src="/Portals/0/20090707_Blog1.jpg" /></span></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: "><span new="" style="line-height: 115%; font-family: ">Then, after a user creates an opportunity where they need help from someone else on they can share that opportunity to the other user and grant them access to see and update the opportunity.</span></span></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: "><span new="" style="line-height: 115%; font-family: "><img alt="" width="500" height="222" src="/Portals/0/20090707_Blog2.jpg" /></span></span></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>PROS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">No custom coding<br />
Uses the standard built-in functionality<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>CONS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Requires users to manually add each person to each opportunity they create or need access to.<span style="mso-spacerun: yes">&#160; </span><br />
Not a simple way to see those who have access to the record.<br />
If a user forgets others who should be able to see it cannot see the opportunity.<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><em>Auto Sharing</em></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">The second option is to use the built-in security options along with an automatic process to automatically share the opportunity to their counterpart.<span style="mso-spacerun: yes">&#160; </span><o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">The solution is to create a security role that only allows users to see and edit opportunities for which they are the owner.<span style="mso-spacerun: yes">&#160; </span>Then, when a user creates an opportunity a custom Plug-in would automatically share out the record to their counterpart based on the owner of the opportunity.<span style="mso-spacerun: yes">&#160; </span>The user would still have to manually share out for the Technical Support because they are assigned on an opportunity by opportunity basis.<o:p></o:p><strong><font size="3"><font color="#4f81bd"><font face="Cambria"><o:p></o:p></font></font></font></strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>PROS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Reduces the user’s manual work to share out records in the system. <br />
Uses the standard built-in functionality with minimal coding.<o:p></o:p></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>CONS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Requires users to manually add each technical support person to each opportunity.<br />
Not a simple way to see those who have access to the record.<br />
If a user forgets others who should be able to see it cannot see the opportunity.<br />
If a field reps counterpart changes could require a code change for the sharing or at least a configuration change.<o:p></o:p></p>
<p style="text-align: justify"><em><span new="" style="line-height: 115%; font-family: ">Auto Sharing using Custom Relationships</span></em></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: ">In this option, we accommodate up to three people who will have access to the opportunity, as stated in our functionality requirements.<span style="mso-spacerun: yes">&#160; </span>We use the built-in security options to lock down the data within CRM.<span style="mso-spacerun: yes">&#160; </span>We then change the label on the Opportunity Form for the standard owner to now say “Field Rep”. We then create two new N:1 relationships from Opportunities to Users.<span style="mso-spacerun: yes">&#160; </span>The first one is called “Inside Rep” and the second one called “Technical Rep”.<span style="mso-spacerun: yes">&#160; </span>We then put the two new fields on the Opportunity Form. We then create a Plug-in on the opportunity that automatically shares the Opportunity to the user that is selected in the Inside Sales or Field Rep relationship.</span></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: "><img alt="" width="500" height="174" src="/Portals/0/20090707_Blog3.jpg" /></span></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>PROS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Shows on the Opportunity form who is working on the opportunity.<br />
Uses the standard built-in functionality with minimal custom code.</p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><u>CONS</u></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">Limits the solution to only three “owners” for each opportunity.<o:p></o:p><strong><font size="5"><font color="#365f91"><font face="Cambria"><o:p></o:p></font></font></font></strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt"><strong>Conclusion</strong></p>
<p class="MsoNormal" style="text-align: justify; margin: 0in 0in 10pt">There are many different ways this version of “multiple owners” can be accomplished within Microsoft CRM.<span style="mso-spacerun: yes">&#160; </span>We covered three simple routes but there are many other ways to accomplish similar functionality.<span style="mso-spacerun: yes">&#160; </span>Your businesses specific requirements along with user training/abilities and volume of data can determine which approach will work best for your business. <o:p></o:p></p>
<p style="text-align: justify"><span new="" style="line-height: 115%; font-family: ">- Hoss Hostetler </span></p>]]></content:encoded><trackback:ping /></item><item><title>Changing the tab order for fields on a form</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/13/Changing-the-tab-order-for-fields-on-a-form.aspx</link><author>Phil Edry</author><guid isPermaLink="false">13</guid><pubDate>Fri, 19 Jun 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">Microsoft Dynamics CRM assumes a vertical tab order within a section. In other words, if you’ve selected a field on a form and press tab, focus will shift to the field below the previous field as opposed to the right of the previous field. This can be frustrating when designing field layout since it is often useful to tab horizontally when filling out a form. This entry will discuss a simple work around using sections without visible headers to allow for horizontal tabbing when appropriate.</span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">Say for example that you have laid out the following fields on a custom entity named Property.</span></span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><img width="500" height="296" alt="" src="/Portals/0/20090616_Blog1.jpg" /></span></span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">If you add all of the fields to a single section, the tab order will go top to bottom on the first column before starting on the second column. So starting from Name, the tab order would above would be Name &gt; Street Address 1 &gt; Street Address 2 &gt; Zip &gt; Status &gt; City &gt; State &gt; Country &gt; Owner. Given our fields, it would make more sense to keep the address fields in a more logical order, so the tab order should be the following: Name &gt; Street Address 1 &gt; Street Address 2 &gt; City &gt; State &gt; Zip &gt; Country &gt; Status &gt; Owner. To achieve this without changing the field layout, “split” the section into multiple sections, but have only the General section display its header.</span></span></span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><img width="500" height="294" alt="" src="/Portals/0/20090616_Blog2.jpg" /></span></span></span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">Note that the two new sections, tabSectionAddress1 and tabSectionAddress2, have grayed out section names and no black line underneath the name. This means that these sections will not be seen as separate form sections by the user, so the final published form will appear the same way, with the only different being the tab order.</span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">Ease of data entry can greatly improve user adoption, so remember to design your forms intelligently with a tab order that makes sense.</span></p>
<p><span style="line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-size: 11pt; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">- Phil Edry <br />
</span></p>]]></content:encoded><trackback:ping /></item><item><title>Export CRM customizations using PowerShell</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/12/Export-CRM-customizations-using-PowerShell.aspx</link><author>Tim Dutcher</author><guid isPermaLink="false">12</guid><pubDate>Wed, 10 Jun 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Microsoft’s “PowerShell” is a command-line shell and scripting language designed for system administration and automation. Its potential benefits to developers and administrators of CRM installations are endless. Since PowerShell can utilize .NET assemblies and web services, it can be used with CRM to automate just about any administration tasks or any other type of routine or tedious tasks.</p>
<div style="margin: 0in 0in 10pt">This blog post provides one example of how PowerShell can make the lives of Microsoft Dynamics CRM 4.0 administrators easier. The script provided below fully automates the process of exporting CRM system customizations to file, which can be scheduled to run at any time interval. It also takes care of creating a unique file name for each export and only keeping customization files that differ from the previous export – thus saving hard drive space.</div>
<div style="margin: 0in 0in 10pt">There are several books and websites dedicated to PowerShell. One site that we’ve found useful is PowerShell.com. Or Bing “powershell” and you’ll find millions of hits. Enjoy!</div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">#######################################################################</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## PowerShell v1.0 Script: CrmCustomizationExporter.ps1</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Purpose: Exports (to an XML file) all CRM 4.0 customizations for the specified organization.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Features:</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; 1) Automatically maintains unique customization files. This reduces storage space and makes it easier to </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160;&#160;&#160;&#160; determine if and when customization were made between exports.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; 2) Reads directly from the CRM WSDL so no local storage of the WSDL (or compiled DLL) is necessary.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Requirements: </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; 1) .NET Framework 2.0 SDK</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; 2) Run script with an account that has rights to export CRM customizations</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; 3) Set the PowerShell execution policy: Set-ExecutionPolicy Unrestricted&#160;&#160;&#160;&#160; (change as appropriate)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Creating a scheduled task:</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##&#160;&#160; - Command to run (example): PowerShell "&amp; c:\ps\CrmCustomizationExporter.ps1"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">##</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New"><span style="font-size: x-small"><span style="font-family: Courier New">#######################################################################</span></span></span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Modify these variables as needed.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$targetDir = "c:\customizations\"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$filePrefix = "customizations_all_"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$crmOrgName = "altriva"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$crmServiceUrl = "http://localhost:5555/mscrmservices/2007/crmservice.asmx"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$wsdlLocation = "$crmServiceUrl" + "?wsdl&amp;uniquename=$crmOrgName"&#160;&#160; # This could also be a fixed file name.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$crmServiceUrl = "$crmServiceUrl" + "?uniquename=$crmOrgName"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">write-host $wsdlLocation</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Open the WSDL.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">[void] [Reflection.Assembly]::LoadWithPartialName("System.Web.Services")</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$wc = New-Object System.Net.WebClient</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$wc.UseDefaultCredentials = $true</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$wsdlStream = $wc.OpenRead($wsdlLocation)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$serviceDescription = [Web.Services.Description.ServiceDescription]::Read($wsdlStream)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$wsdlStream.Close()</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Import the web service into a CodeDom.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$serviceNamespace = New-Object System.CodeDom.CodeNamespace</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$codeCompileUnit = New-Object System.CodeDom.CodeCompileUnit</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$serviceDescriptionImporter = New-Object Web.Services.Description.ServiceDescriptionImporter</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$serviceDescriptionImporter.AddServiceDescription($serviceDescription, $null, $null)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">[void] $codeCompileUnit.Namespaces.Add($serviceNamespace)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">[void] $serviceDescriptionImporter.Import($serviceNamespace, $codeCompileUnit)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Generate the code from that CodeDom into a string.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$generatedCode = New-Object Text.StringBuilder</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$stringWriter = New-Object IO.StringWriter $generatedCode</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$provider = New-Object Microsoft.CSharp.CSharpCodeProvider</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$provider.GenerateCodeFromCompileUnit($codeCompileUnit, $stringWriter, $null)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Compile the source code.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$references = @("System.dll", "System.Web.Services.dll", "System.Xml.dll")</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$compilerParameters.ReferencedAssemblies.AddRange($references)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$compilerParameters.GenerateInMemory = $true</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $generatedCode)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Get the assembly that we just compiled.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$assembly = $compilerResults.CompiledAssembly</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Create an instance of the CrmService type.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$type = "CrmService"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$instance = $assembly.CreateInstance($type)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Set instance properties.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$instance.UseDefaultCredentials = $true</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$token = new-object CrmAuthenticationToken </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$tokenAuthenticationType=0 </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$Token.OrganizationName = $crmOrgName</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$instance.Url = $crmServiceUrl</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$instance.CrmAuthenticationTokenValue = $token </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$CrmCredentials = [System.Net.CredentialCache].DefaultCredentials </span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Execute the customization export request</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$request = new-object "ExportAllXmlRequest"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$response = $instance.Execute($request) -as [ExportAllXmlResponse]</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$responseXml = new-object XML</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$responseXml.LoadXml($response.ExportXml)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## Write the exported customizations XML to a date-stamped file.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$date = (get-date).ToString('yyyyMMdd_HHmmss')</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$xmlfile = "$targetDir$filePrefix$date.xml"</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$responseXml.Save("$xmlfile")</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">## If the previous export file is the same size as the file just created then delete the previous version.</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">$XmlFiles = Get-ChildItem "$targetDir*.xml" | Sort-Object -Descending</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">if ($XmlFiles.count -gt 1)</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">{</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;$previousXmlFile = $XmlFiles[1]</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;$previousXmlFileSize = (Get-Item $previousXmlFile).length</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;write-host $previousXmlFileSize</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">&#160;if ($previousXmlFileSize -eq (Get-Item $xmlfile).length) { Remove-Item $previousXmlFile }</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt"><span style="font-size: x-small"><span style="font-family: Courier New">}</span></span></div>
<div style="line-height: normal; margin: 0in 0in 0pt">&#160;</div>
<div style="line-height: normal; margin: 0in 0in 0pt">- Tim Dutcher</div>
<p>&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>Making “Send Shortcut” functionality work internally as well as over IFD in CRM 4.0</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/11/Making-“Send-Shortcut”-functionality-work-internally-as-well-as-over-IFD-in-CRM-4.0.aspx</link><author>Phil Edry</author><guid isPermaLink="false">11</guid><pubDate>Fri, 29 May 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Did you know that you can send a hyperlink shortcut to an entity in CRM 4.0 over email? This functionality is especially useful when team members are collaborating on a customer or case together and want an easy way to link to what they’re working on so that the collaborating team member won’t have to search for the record to find it. But what happens if one team member connects to CRM 4.0 over the company intranet, while the other team member connects using IFD (Internet Facing Deployment)? Depending on network infrastructure, chances are that the sent shortcut will not work for both users. This blog entry will describe a workaround for this scenario.</p>
<p>Say you’re on an opportunity and you’d like to email a shortcut to a colleague so that you can collaborate on it. From an open Opportunity window, you can select the Actions menu, and then “Send Shortcut…” which will open up a new email with your default mail client (usually Outlook).</p>
<p><img width="500" height="420" alt="" src="/Portals/0/20090529BlogPic2.jpg" /></p>
<p>This leaves you with the option to alter the email body and add as many recipients as you see fit.</p>
<p>The downside to this approach is that depending on your network infrastructure and IFD configuration, you may get a different shortcut URL when you do the same operation over IFD:</p>
<p><img width="500" height="419" alt="" src="/Portals/0/20090529BlogPic3.jpg" /></p>
<p>This could cause a problem if your network infrastructure and IFD deployment settings are such that internal URLs only work internally (intranet) and/or external URLs only work externally (over IFD). Here are two workarounds to this issue:</p>
<p><b>Workaround 1: Configure your network and IFD settings to support the IFD URLs internally and configure each outlook client to only use the IFD URL.</b> As an example, say that your external IFD URL is <a href="https://altriva.altriva.com/"><u><font color="#0000ff">https://altriva.altriva.com</font></u></a>. If you have the ability to configure your network to also recognize this URL internally, then you have the option to configure CRM for Outlook to only use this URL, instead of one URL when connected to your Intranet and another URL when not connected to your Intranet. This way, the send shortcut functionality will always send the IFD URL and the link will work both internally and externally.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><strong>Workaround 2: Create two custom buttons or menu options on each entity you want to support, where one button sends an internal link and the other button send an external link.</strong></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><span style="font-size: small"><span style="font-family: Arial"><img alt="" width="419" height="86" src="/Portals/0/20090529BlogPic4.jpg" /></span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">To implement this workaround, you will need to modify the XML in the isv.config to include some JavaScript. The following XML from isv.config is an example of one way to accomplish this for the Account entity (see <a href="http://msdn.microsoft.com/en-us/library/bb928136.aspx">http://msdn.microsoft.com/en-us/library/bb928136.aspx</a> to learn how to modify your isv.config).</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><span style="font-size: x-small"><span style="font-family: Courier New"><span style="line-height: 115%; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Entity name="account"&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;MenuBar&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;CustomMenus&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Menu&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Title LCID="1033" Text="Send Shortcut" /&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;MenuItem JavaScript="OpenEmailForm('', crmForm.all.name.DataValue, crmForm.all.new_internalshortcut.DataValue);" PassParams="0" WinMode="1"&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Title LCID="1033" Text="Send Internal Shortcut" /&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/MenuItem&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;MenuItem JavaScript="OpenEmailForm('', crmForm.all.name.DataValue, crmForm.all.new_externalshortcut.DataValue);" PassParams="0" WinMode="1"&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Title LCID="1033" Text="Send External Shortcut" /&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Titles&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/MenuItem&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Menu&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/CustomMenus&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/MenuBar&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;NavBar&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/NavBar&gt;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Entity&gt;</span></span></span><span style="font-family: Arial"><span style="font-size: small"><span style="line-height: 115%; mso-fareast-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><br />
</span></span></span></p>
<p>The above code assumes that two fields named new_internalshortcut and new_externalshortcut have already been added to the account form and contain the complete URLs for the internal and external shortcuts respectively. In my solution, I populated these two fields through direct SQL updates for existing data, and then with JavaScript OnSave of the account entity for future data. Note that direct SQL updates are considered to be unsupported customizations, but this direct SQL update is relatively low risk.</p>
<p>The new_internalshortcut and new_externalshortcut fields are not technically required, and in fact could be derived directly in the isv.config JavaScript by appending “&lt;&lt;urlroot&gt;<urlroot></urlroot>&gt;/sfa/accts/edit.aspx” and the crmForm.ObjectId, but I will leave that as an exercise to the reader. Note also that the below XML calls a mysterious function called “OpenEmailForm(string, string, string)”. This is an internal CRM JavaScript function that creates the appropriate “mailto” statement we need, and is exactly what is called by the existing “Send Shortcut” functionality. Calling internal CRM JavaScript functions are completely unsupported, and there is a good chance that this code will not work after an upgrade. To avoid this, you could replace the OpenEmailForm function with a direct <a href="http://www.w3schools.com/HTML/tryit.asp?filename=tryhtml_mailto">mailto</a> statement, which would keep your CRM system in a supported state.</p>
<p>Always be sure to backup your database before editing the isv.config file. CRM 4.0 does a better job than CRM 3.0 at detecting invalid isv.config files before it imports them, but you still run the risk of hosing your UI. If you find this high level approach to the workarounds a little lacking in detail, you may want to consider bringing in a CRM expert or consultant to help fill in the details to make sure your systems stays up after implementation.</p>
<p>- Phil Edry</p>]]></content:encoded><trackback:ping /></item><item><title>The Microsoft Dynamics CRM 4.0 Resource Center – What it’s good for and how to remove it</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/10/The-Microsoft-Dynamics-CRM-4.0-Resource-Center-–-What-it’s-good-for-and-how-to-remove-it.aspx</link><author>Phil Edry</author><guid isPermaLink="false">10</guid><pubDate>Sat, 02 May 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p><span new="" style="line-height: 115%; font-family: ">The Microsoft Dynamics CRM 4.0 Resource Center can either be a valuable tool to encourage user adoption or if it’s not used, it can clutter users’ screens without any value add. This post will discuss what the Resource Center is good for, and if you don’t buy it (or if your users do not have access to the internet from their workstations) we’ll also discuss how to remove the Resource Center to open up valuable screen real estate. </span></p>
<p><span new="" style="line-height: 115%; font-family: ">By default, the Resource Center is added as a “Group” in CRM just like Workplace, Sales, Marketing, Service, and Settings are Groups. Via the web client, the Resource Center is accessible by simply clicking the Resource Center group.</span></p>
<p>&#160;<span new="" style="line-height: 115%; font-family: "><img alt="" width="197" height="196" src="/Portals/0/20090501Blog1.jpg" /></span></p>
<p>&#160;Via the CRM for Outlook client, the Resource Center appears alphabetically with the other CRM groups.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><img alt="" width="178" height="141" src="/Portals/0/20090501Blog2.jpg" /></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">The Resource Center has quite a bit of content on it, some of which is applicable to typical CRM users, some of which is applicable really only to admins and super users. One of my favorite pieces of the Resource Center is the Getting Started Videos.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><img alt="" width="377" height="91" src="/Portals/0/20090501Blog3.jpg" /></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">There are three videos that can be quite eye opening to users who are new to the system. The videos are high quality, and can really convince Marketing and Management that Microsoft Dynamics CRM 4.0 is much more powerful than a simple contact aggregator. Altriva teaches Advanced Find as a topic in user training, but it doesn’t always sink in the first time. A quick video refresher can help solidify CRM concepts introduced in training.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">Still not sold? Think it’s just a bunch of clutter, or maybe it’s just not right for your business? Then remove it with the below steps. Anyone can still access the resource center by going to the following link in a web browser: <a href="http://rc.crm.dynamics.com/rc/regcont/en_us/opdefault.aspx"><u><font color="#0000ff">http://rc.crm.dynamics.com/rc/regcont/en_us/opdefault.aspx</font></u></a></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">The following is taken directly from the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1ceb5e01-de9f-48c0-8ce2-51633ebf4714&amp;displaylang=en"><u><font color="#0000ff">Microsoft Dynamics CRM Installing Guide</font></u></a> (4.4.0, pages 123-124)<span style="font-family: "><font size="2"><o:p></o:p></font></span></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in; mso-list: l1 level1 lfo4"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">1.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Export the SiteMap by using the Export Customizations feature.</font></p>
<p class="ListAlpha2" style="margin: 3pt 0in 3pt 0.5in; mso-list: l2 level1 lfo5"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">a.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">In the Navigation Pane, click <span class="UIItem"><strong>Settings</strong></span>, click <span class="UIItem"><strong>Customization</strong></span>, and then click <span class="UIItem"><strong>Export Customizations</strong></span>.</font></p>
<p class="ListAlpha2" style="margin: 3pt 0in 3pt 0.5in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">b.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160; </span></span></span><font size="2" face="Arial">Select SiteMap, then on the <span class="UIItem"><strong>Actions</strong></span> toolbar, click <span class="UIItem"><strong>More Actions</strong></span>, and then click <span class="UIItem"><strong>Export Selected Customizations</strong></span>.</font></p>
<p class="ListAlpha2" style="margin: 3pt 0in 3pt 0.5in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">c.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Save the customization compressed (.zip) file and make a copy of it as a backup.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">2.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Extract the <span class="FileName"><strong>customization.xml</strong></span> file from the <span class="FileName"><strong>customization.zip</strong></span> file.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">3.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Open the <span class="FileName"><strong>customization.xml</strong></span> file by using a text editor such as Microsoft Visual Studio or Notepad.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">4.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Locate the following node in the file.</font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font face="Courier New" style="background-color: #e6e6e6">/ImportExportXml/SiteMap/SiteMap/Area Id="ResourceCenter"</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">5.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Comment the Area by using &lt;!-- and -- &gt; tags where the Id attribute is set to "ResourceCenter" as follows:</font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font face="Courier New" style="background-color: #e6e6e6">&lt;!--&lt;Area Id="ResourceCenter"</font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;</span>ResourceId="Area_ResourceCenter"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;</span>Icon="/_imgs/resourcecenter_24x24.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;</span>DescriptionResourceId="ResourceCenter_Area_Description"&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;</span>&lt;Group Id="ResourceCenter"&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span>&lt;SubArea Id="nav_lc_overview"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>ResourceId="Homepage_LearningOverview"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>DescriptionResourceId="LearningOverview_SubArea_Description"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Icon="/_imgs/ico_18_129.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Url="/resourcecenter/overview.aspx"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>AvailableOffline="false" /&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span>&lt;SubArea Id="nav_lc_sales"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>ResourceId="Homepage_LearningSales"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>DescriptionResourceId="LearningSales_SubArea_Description"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Icon="/_imgs/ico_16_sales.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Url="/resourcecenter/sales.aspx"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>AvailableOffline="false" /&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span>&lt;SubArea Id="nav_lc_marketing"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span><span style="mso-spacerun: yes">&#160;</span>ResourceId="Homepage_LearningMarketing"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>DescriptionResourceId="LearningMarketing_SubArea_Description"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Icon="/_imgs/ico_16_marketing.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Url="/resourcecenter/marketing.aspx"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>AvailableOffline="false" /&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span>&lt;SubArea Id="nav_lc_services"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>ResourceId="Homepage_LearningServices"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>DescriptionResourceId="LearningServices_SubArea_Description"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Icon="/_imgs/area/18_service.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Url="/resourcecenter/services.aspx"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>AvailableOffline="false" /&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160; </span>&lt;SubArea Id="nav_lc_customization"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>ResourceId="Homepage_LearningCustomization"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>DescriptionResourceId="LearningCustomization_SubArea_Description"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Icon="/_imgs/area/18_settings.gif"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>Url="/resourcecenter/customization.aspx"</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;&#160; </span>AvailableOffline="false" /&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font style="background-color: #e6e6e6"><font face="Courier New"><span style="mso-spacerun: yes">&#160;</span>&lt;/Group&gt;</font></font></p>
<p class="Code" style="margin: 0in 0in 0pt 17.3pt"><font face="Courier New" style="background-color: #e6e6e6">&lt;/Area&gt;--&gt;</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">6.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Make your changes to the <span class="FileName"><strong>customization.xml</strong></span> file.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">7.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Import the updated XML file by using the Import Customizations feature.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">8.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">In the Navigation Pane, click <span class="UIItem"><strong>Settings</strong></span>, click <span class="UIItem"><strong>Customization</strong></span>, and then click <span class="UIItem"><strong>Import Customizations</strong></span>.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">9.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160;&#160;&#160;&#160; </span></span></span><font size="2" face="Arial">Locate your modified XML file and then click <span class="UIItem"><strong>Upload</strong></span>.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in"><span style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font size="2" face="Arial">10.</font><span style="font: 7pt &quot;Times New Roman&quot;">&#160; </span></span></span><font size="2" face="Arial">On the <span class="UIItem"><strong>Actions</strong></span> toolbar, click <span class="UIItem"><strong>Import All Customizations</strong></span>.</font></p>
<p class="MsoListNumber" style="margin: 3pt 0in 3pt 0.25in">&#160;</p>
<p class="MsoListNumber" style="margin-top: 3pt; margin-bottom: 3pt; margin-right: 0in"><span style="font-family: "><o:p>- Phil Edry</o:p></span></p>]]></content:encoded><trackback:ping /></item><item><title>Success with Microsoft Dynamics CRM 4.0 Kindle Edition now available</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/9/Success-with-Microsoft-Dynamics-CRM-4.0-Kindle-Edition-now-available-.aspx</link><author>Phil Edry</author><guid isPermaLink="false">9</guid><pubDate>Sun, 05 Apr 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p><span new="" style="line-height: 115%; font-family: ">Success with Microsoft Dynamics CRM 4.0, the book that Altriva published last December, is now available on your Kindle. Now you can learn about how to successfully plan and deliver a Microsoft Dynamics CRM 4.0 implementation from the convenience of your handheld device.</span></p>
<p><span new="" style="line-height: 115%; font-family: ">Click on the picture:</span></p>
<p><span new="" style="line-height: 115%; font-family: "><a href="http://www.amazon.com/Success-Microsoft-Dynamics-CRM-4-0/dp/B001WAJYC2"><img alt="" width="280" height="280" src="/Portals/0/bookKindleEdition.jpg" /></a></span></p>
<p>&#160;</p>]]></content:encoded><trackback:ping /></item><item><title>How to trigger reminders off dates within Microsoft CRM</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/8/How-to-trigger-reminders-off-dates-within-Microsoft-CRM.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">8</guid><pubDate>Tue, 03 Mar 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0in 0in 10pt">This past month a few questions were asked in the CRM newsgroup and forums about how to trigger reminders off of dates within Microsoft CRM. &#160;I thought this would be a good discussion topic to discuss the options along with some Pros and Cons of each option.</p>
<p>A few examples of the questions we have seen are:</p>
<p>“Let’s say I want to be notified 3 days in advance about birth dates of all the contacts in the system”<br />
“I want a reminder sent to the owner of a case 3 days before the due date of the case”<br />
“Is there a way to send a note to a manager if a case is untouched after 4 hours”</p>
<p>As with most requirements around Microsoft CRM there are multiple ways we can accomplish getting the reminder requested in each of these instances.&#160; When we look at the different ways each one can be accomplished we need to understand what the actual business process we are trying to facilitate is and then look at our options.&#160; Once we know our options and what business process we are trying to facilitate we can then decide based on our company's abilities or the abilities of our implementation partner which approach will work best for us.</p>
<p>Microsoft CRM allows this to be accomplished through many avenues:</p>
<ul>
    <li>Passively (The user must do something to be reminded); a view or report<br />
    &#160;</li>
    <li>Actively (The user receives the reminder without doing anything); schedule a report, creating a workflow or a custom application.</li>
</ul>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><strong>Build a View</strong></p>
<p>The simplest to build is a simple view either via Settings --&gt;Customizations --&gt; Customize Entities or via Advanced Find and then sharing it out.&#160; This view is very simple to create and will show you all open cases due in the next 3 days anytime a user goes to it.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><font face="Calibri"><span style="mso-spacerun: yes"><img alt="View Creation Image" width="500" height="393" src="/Portals/0/20090302Pic1.jpg" /></span></font></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">This would make the view available in the case section of Microsoft CRM.&#160; This will work but it requires the users to look at the view each day to make sure there are no cases due in the next few days.&#160; This solution is very simple to complete and does not require any custom code and does not cause any performance concerns.&#160; All you have to do is then train users to look at the view of "open cases due in the next 3 days" and enforce this process with review of the view by managers also to make sure things are happening.</p>
<p><strong>Build a Report</strong></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">This is the next simplest route to go is to either use the Report Wizard to build a report or use the SSRS report designer to build a simple case report.&#160; &#160;If you are using CRM Online then you should use the Report Wizard because currently you are not allowed to load custom reports built using SSRS report designer.&#160; Once you have created the report you can make it available from the reports section and from the case area via the reports icon.&#160;</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><font face="Calibri"><span style="mso-spacerun: yes">&#160;<img alt="Case Report Dropdown Menu Image" width="200" height="208" src="/Portals/0/20090302Pic2.jpg" /><img alt="Report Area Image" width="500" height="173" src="/Portals/0/20090302Pic3.jpg" /></span></font></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">As with the view this is a very simple way to get this information to your users but it is a passive reminder because the user must remember to run the report each day to see the Cases that have a due date in the next 3 days.&#160; The positives are that if you used the Report Wizard there was no special tool to learn and no custom work to build or deploy and you once again have no performance issues to worry about.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><strong>Build a Report and send it via E-mail (Not able to be done if using CRM Online)</strong></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">If you are using CRM On-Premise you can create the same report using either the Report Wizard or SSRS Report Designer that shows the cases with a due date in the next 3 days.&#160; You can then schedule the report within SSRS to use stored credentials and automatically send the report to a user or a group of users each morning.&#160; This is less passive because the users do not have to remember to go to a view or run a report within Microsoft CRM but the users still must open the report in the e-mail and review the open cases.</p>
<p class="MsoNormal" style="margin: 0in 0in 10pt"><strong>Use Workflow</strong></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">This is possible in workflow depending on how you want the reminder (Outlook Reminder or E-mail) to happen and how your users are using the system.&#160; <o:p></o:p></p>
<p>If your users are using the Outlook client and synchronizing tasks to their outlook then you can very easily have a workflow on create of case first wait for the due date to be filled in and then create a task due 3 days before the due date that was entered which will pop up in their outlook as a reminder to work on the case.&#160; The problem with this approach is if they do not use the outlook client or decide not to sync tasks to Outlook they will not get a reminder pop up and will then just need to be looking at their tasks due in CRM. &#160;Another problem is if you only want the reminder to go out when the case is within 3 days of the due date this does not work because this will make a task for all cases when the due date is filled out. <o:p></o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">A second approach using workflow would be to create a workflow that basically checks once a day and then send out an e-mail to the owner if it is within 3 days of the due date for the case.&#160; This workflow would be pretty simple:<o:p></o:p></p>
<p style="margin-left: 40px">a. It would first have a wait condition that waited 24 hours<br />
b. It would check if they case is still open if so continue otherwise end workflow<br />
c. If the case is still open it would check if the Due Date is less the 3 days greater than the workflow execution time. If so it would create an e-mail and send it to the owner of the case.<br />
d. It would start a new instance of that workflow again. <o:p></o:p></p>
<p>The good part with this second option is it only sends the reminder if the case is still open and within the 3 days of the due date.&#160; The bad part is that it means you have at least one workflow running for each case you have open.&#160; This can cause a performance burden on your system depending on the number of cases you have.&#160;&#160; If you have lots of cases this is something to consider before you decide to implement this solution.</p>
<p><strong>Custom Application </strong></p>
<p class="MsoNormal" style="margin: 0in 0in 10pt">This will be a development effort and you can approach it multiple ways depending on your developer’s skill set and if you are using CRM Online or On-Premise.&#160; Your developers could build a simple tool that runs hourly or daily and it could query CRM for open cases due in less than three days. &#160;You can query against the SQL views (On-Premise only) in the database and send an e-mail or you can build it to query through the API's (Online or On-Premise) and either send an e-mail or create new tasks or e-mails within CRM.&#160;</p>
<p><strong>Summary</strong></p>
<p>The route you choose depends on the actual business process you are trying to facilitate and your company’s abilities or partner's abilities in development and CRM architecture. All of the above will work with varying degrees depending on your specific business process requirement.</p>
<p>- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Execution Pipeline Overview</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/7/Execution-Pipeline-Overview.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">7</guid><pubDate>Fri, 30 Jan 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>We have brought up synchronous and asynchronous processing multiple times throughout previous posts thus far related to Custom Workflow Assemblies and Plug-ins in Microsoft Dynamics CRM 4.0. The next section will cover in more detail the business and technical impacts of both types of event registration within the Execution Pipeline.</p>
<p><strong>Execution Pipeline Synchronous vs. Asynchronous Overview</strong></p>
<p>The Microsoft Dynamics CRM 4.0 Execution Pipeline allows for synchronous and asynchronous event processing. Synchronous events execute one at a time, either before or after CRM Platform Core Operations (Create, Delete, Update, etc). Asynchronous events are added to the asynchronous event queue to be executed by the asynchronous process at some point in the near future.</p>
<p>The business impact of using synchronous and asynchronous events is more easily understood with the help of examples. The following two hypothetical examples detail two scenarios where events could be registered synchronously or asynchronously to satisfy a business requirement. While the scenarios will function with either registration method, there are advantages and disadvantages to the method as described below.&#160;</p>
<p><strong>Example 1: Account to Contact Cascading Addresses&#160;</strong></p>
<p>CRM users have requested an extension to Microsoft Dynamics CRM 4.0 that would update the addresses for all sub-contacts for an account when the account’s address changes. You write code to check if the address has changed on save of an account. If so, you retrieve the sub-contact records and iterate through the records to update each contact’s address. You now must decide if you should register the code synchronously or asynchronously.</p>
<p>If you register the event to run synchronously, users will have to wait for all of the sub-contacts to be retrieved, edited, and saved before form control is returned to the user after clicking save. The up side to this approach is that the user could be sure that once the full save event finishes, all sub-contacts would immediately reflect the address change. The down side is that user experience could become extremely sluggish when working with large accounts with many sub-contacts or when bulk-editing multiple accounts.</p>
<p>If you instead register the event asynchronously, the sub-contacts will be processed in the background (with a slight delay) without affecting user experience. The one downside occurs in the corner case when a user saves an address change for an account and then quickly opens a sub-contact record to see if the address was updated. There might be some user confusion if the asynchronous process had not yet updated the contact record. Since this is a rare corner case and it can be avoided through training, registering asynchronously is the clear choice to avoid performance issues.</p>
<p><strong>Example 2: Custom Case Number Generation with Immediate Feedback</strong></p>
<p>CRM customer service users track customer support information using the case entity in CRM. When a new case is created, an email is sent to the customer providing them their case number. The business has decided not to use the out-of-box CRM case number functionality, since they require an abbreviation of the case subject to appear in the case number in order to more easily categorize cases by topic outside of CRM.</p>
<p>When a user is in the process of creating a new case, they first ask the customer the nature of the call and choose a case subject. You write code that executes on save to generate a new case number and include an abbreviation of the subject appended to the number. You then create a workflow to send an email to the customer using an email template that retrieves the newly-generated case number.</p>
<p>At the end of a service call, customer server representatives would also like to verbally communicate the case number to the customer. If you register the .NET assembly asynchronously, service users would have to do an initial save on the case and then continuously refresh the case form until the asynchronous process gets around to updating the case with the case number. Synchronous registrations allows for the field to be updated on the case form as soon as the save event completes, allowing the representative to quickly provide a case number to the customer. Synchronous Plug-in registration is the clear choice in this case.</p>
<p><strong>Conclusion</strong></p>
<p>These two examples have quickly highlighted some the advantages and disadvantages of using asynchronously or synchronously processing of you custom business logic.&#160; When deciding which route to take you need to understand how each will impact the user.&#160;&#160; Will waiting for a response interrupt the process flow within the application or will not having the confirmation or custom logic result interrupt the process flow.&#160; With each area of process automation we need to examine the best approach to facilitate the intended business process.</p>
<p>- Phil Edry &amp; Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Custom Extensions – Custom Workflow Activities vs. Plug-ins</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/6/Custom-Extensions-–-Custom-Workflow-Activities-vs.-Plug-ins.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">6</guid><pubDate>Fri, 16 Jan 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Today’s CRM Success blog entry will focus on when to use Workflows with Custom Workflow Activities (AKA Workflow Assemblies) and when to use Plug-ins when registering .NET assemblies to help facilitate business processes in CRM.</p>
<p><strong>Workflows with Custom Workflow Activities vs. Plug-ins in Microsoft Dynamics CRM 4.0</strong></p>
<p>We will start with high-level guidelines of when to use each tool and then get into the specifics of how the tools work within the Microsoft Dynamics CRM 4.0 Execution Pipeline with regards to the synchronous and asynchronous processing of events in a later blog post. We will not get into definitions of <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc151142.aspx">Custom Workflow Activities</a> and <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc151086.aspx">Plug-ins</a> or provide <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc151207.aspx">code samples</a> since these are accessible from the CRM SDK documentation (click links to view).</p>
<p>As described in an earlier post “<a target="_blank" href="http://www.altriva.com/AltrivaBlog/tabid/61/EntryId/4/Custom-Extensions-Discussion-Intro.aspx">Custom Extensions Discussion - Intro</a>”:</p>
<p style="margin-left: 40px">The best way to approach the custom extension capabilities of Microsoft Dynamics CRM 4.0 is to first fully understand your business processes, specifically which parts of those processes are causing you pain or costing your business money. The next step is to build those processes into CRM using the base CRM functionality and then re-examining your system to see which pain points remain. Then, with a good working understanding of all the ways you can extend Microsoft CRM, design your custom extensions to relieve the remaining pain points while taking into account the pros and cons of each custom extension approach.</p>
<p>Creating workflows through the CRM client (without calling custom assemblies) is a powerful way to improve business process facilitation. Basic workflow provides many benefits: no need for .NET expertise to develop, easy to modify (no code changes required), and you can export and import them like customizations. However, basic workflow also has its functional limitations. Fortunately, Microsoft Dynamics CRM 4.0 supports Custom Workflow Activities and Plug-ins for calling custom .NET assemblies to extend beyond basic workflow limitations. Given their similarities, it can be difficult to decide which method to use. Below are guidelines to consider when choosing your extension tool.</p>
<p><strong>High-level Usage Guidelines</strong></p>
<ol>
    <li><strong>Custom Workflow Activities can only execute.NET assemblies asynchronously, while Plug-ins can execute .NET assemblies both synchronously and asynchronously.</strong> If you have already decided that your extension needs to execute synchronously, the choice is simple: Plug-ins are the only way to go. Synchronous and asynchronous event execution will be covered in detail in a following post with a description of the Execution Pipeline Synchronous vs. Asynchronous and examples.</li>
    <li><strong>If your .NET assembly is one step in a multi-step workflow, use Custom Workflow Activities.</strong> Workflow maintenance is simplified when all of the processing logic is in one place. This is especially true if a business process requires a mix of basic steps and Custom Workflow Activities to occur in a specific order. If you instead put your basic steps in a workflow and register you custom code as an asynchronous Plug-in, you’d have two places to maintain the processing logic and you would not be able to control the order in which the plug-in and workflow execute.</li>
    <li><strong>If you want to track a history of when your .NET assembly was run against an entity, use Custom Workflow Activities. Otherwise, use Plug-ins.</strong> Each time a workflow runs, a record of it is audited in CRM. This can be useful in some cases and distracting or unnecessary in other cases.</li>
    <li><strong>If you want the flexibility to easily disable or change what triggers a .NET assembly without changing code, use Custom Workflow Activities.</strong> Using Custom Workflow Activities within a workflow gives you the flexibility to publish and un-publish changes to the “Start when:” settings on the workflow form. It also allows users to run .NET assemblies against records as an on demand workflow.&#160; The ability to quickly remove or add in custom logic to a workflow that business users can control can be very helpful especially with processes that are either dynamic or will be changing frequently.</li>
    <li><strong>If none of the above applies, it comes down to personal preference. We suggest Plug-ins.</strong> Generally speaking, it simplifies business logic maintenance to manage most of your .NET assemblies in the same place. Since Plug-ins can do both synchronous and asynchronous processing, and there is a good chance your system will require synchronous plug-ins at some point, it makes sense to register the asynchronous .NET assemblies as Plug-ins as well.</li>
</ol>
<p><strong>Conclusion</strong></p>
<p>To close, there are quite a few things to consider when deciding when to use Workflows with Custom Workflow Activities and when to use Plug-ins. If you intend to register your .NET assembly synchronously or you don’t intend to leverage any of workflow’s basic functionality, use a Plug-in. If you’re ok with asynchronous processing and your .NET assembly is a sub-process in a contiguous workflow, you want an audit history, or you want to ease event trigger administration, use a Custom Workflow Extension.</p>
<p>- Phil Edry &amp; Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Custom Extensions – JavaScript using API’s vs. Plug-ins</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/5/Custom-Extensions-–-JavaScript-using-API’s-vs.-Plug-ins.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">5</guid><pubDate>Sat, 03 Jan 2009 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>Once we have defined the processes we want to capture within our CRM system and we have begun our design and captured a user's usage scenarios, we often find places where custom code can help with automating some user processes to make them more efficient or enforce data validation.</p>
<p>There are many different options to automate business processes within Microsoft Dynamics CRM 4.0.&#160; Today we will look at the differences between doing it via JavaScript that calls back into the CRM API’s versus using Plug-ins.</p>
<p><strong>Automating Business Processes: Using JavaScript to Call API's vs. Plug-ins</strong></p>
<p>Data validation and retrieval from other CRM entities or systems are often useful when automating business processes. There are multiple ways you can accomplish these tasks in Microsoft CRM. Two frequently used methods are synchronous plug-ins and form-level JavaScript calling either the CRM API's or integrating with another system.</p>
<p>One benefit to using JavaScript is that since JavaScript is run on the form (client-side), it can react to any OnChange or OnLoad event on the form and provide immediate feedback to users. In other words, users do not have to wait until saving the form for data validation or retrieval to take place. Additionally, client-side JavaScript allows for greater flexibility when communicating messages to the user, as well as with field manipulation. JavaScript's downside is that since it runs client-side, it requires more roundtrips between the server and client. This approach is not an issue if most users have good connections to the server. However, a client-side approach can impact performance in the case of a deployment with users spread across multiple offices or with users having slow server connections. Furthermore, creating an additional client-side connection to the CRM server or other external servers can break functionality when a user is offline or cannot access the external server. Another point to consider is that the use of client-side scripting transfers additional processing load from the server to the client</p>
<p>To contrast, Plug-ins in Microsoft Dynamics CRM 4.0 run server-side and therefore do not offload any processing load to the client. This is usually a non-issue unless your CRM server is underpowered. With server-side processing, the performance impact will be the same for all users no matter where they access CRM from. Another benefit is that the Microsoft CRM Plug-in model has built in ways to handle online and offline processing that are described in the CRM SDK. The downsides of using Plug-ins are that a user must click save to trigger the Plug-in and there are a limited set of responses you can send to the user from within your plug-in.</p>
<p>Both Plug-ins and JavaScript scripting to call API's have their uses. For example, JavaScript is a viable choice and could be the best solution if you are building a solution for a call center where all users have consistently fast connections and immediate data validation response helps their business process. On the other hand, if you have a dispersed workforce with slow or limited connections to CRM server, then the plug-in model might work better for you. One roundtrip on-save that results in an error message might be much quicker than waiting for multiple server roundtrips after each field is filled out.</p>
<p>- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Custom Extensions Discussion - Removing Unused Entities</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/4/Custom-Extensions-Discussion---Removing-Unused-Entities.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">4</guid><pubDate>Sat, 20 Dec 2008 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<p>The first comparison we will look into is how we can remove sections of the application or functionality that a business is currently not using or plans on never using within Microsoft Dynamics CRM 4.0.&#160;</p>
<p><strong>Removing Unused Entities via SiteMap vs. Security</strong></p>
<p>Microsoft Dynamics CRM 4.0 has a full CRM suite of functionality built in out of the box encompassing Sales, Service, and Marketing. Most implementations of Microsoft Dynamics CRM 4.0 will not use the entire set of the CRM functionality, and in many cases, exposing unused functionality to the users can reduce the usefulness of the overall system. Removing unused areas or entities within MS CRM can make the MS CRM application much easier for a user to grasp.</p>
<p>Figure 1: User sees all links in the main navigation and the related section of the Account, which can be very distracting to users.</p>
<p style="text-align: center"><img alt="Figure 1" width="364" height="562" src="/Portals/0/blog_20081220_fig1.jpg" /><br />
<span style="font-size: smaller">Figure 1<br />
</span></p>
<p style="text-align: left">Figure 2: Shows the links pared down to the three they use currently in Sales and removed all the sections they do not use on the account related form.&#160; This was done quickly through security.</p>
<p style="text-align: center"><img alt="Figure 2" width="368" height="558" src="/Portals/0/blog_20081220_fig2.jpg" /><br />
<span style="font-size: smaller">Figure 2</span></p>
<p style="text-align: left">SiteMap customization is a tool in Microsoft Dynamics CRM 4.0 that allows you to customize the main navigation pane by modifying XML. The good part about editing the SiteMap is that you can quickly remove areas of the application so that users do not see those pieces of the application in their clients. This can be really helpful within the outlook client because you can limit the CRM folders to only display the folders users will use. The big drawback to removing unused areas or entities via the SiteMap is that it applies to all users in the application, regardless of role. This means you cannot use the SiteMap to hide the Sales area for the Service team and hide the Service Area for the Sales team. Another drawback to using the SiteMap to remove certain entities is that it removes them from the main application navigation, but they will still show up on related entity forms.</p>
<p style="text-align: left">Using Role Based Security to limit access by itself or in conjunction with SiteMap modifications is usually a better route to remove unused entities from users' views. Building security roles allows for differences among groups/users regarding which pieces of functionality are displayed in CRM forms as well as in the main navigation.</p>
<p style="text-align: left">When deciding how to hide pieces of functionality in Microsoft Dynamics CRM 4.0, the first question to ask yourself is will a currently-unused piece of functionality be useful sometime in the future. Where possible, it is usually preferable to take away the right to see an object via security rather than just removing it from the sitemap. This is especially is true if you try to add the functionality back in later since users with the System Administrator role will still have access to the hidden entities and can quickly extend visibility to other roles.</p>
<p style="text-align: left">In addition to hiding CRM functionality, SiteMap customization can be used to add new links to external systems or to rearrange the main application navigation to group things together to better fit your business processes.</p>
<p style="text-align: left"><strong>Note</strong>: This only looks at two ways, which tend to be most often used, to accomplish removing/hiding functionality within Microsoft Dynamics CRM 4.0.&#160;&#160; Other options exist such as unsupported JavaScript, unsupported base CRM page modification, rebuilding system entities using custom entities to not have related items you do not use and many others options.&#160; Each option has different Pro’s and Con’s that you need to think about.&#160; We will look into some of these other options in future posts.</p>
<p style="text-align: left">- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Success with Microsoft Dynamics CRM 4.0 on bookshelves now!</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/3/Success-with-Microsoft-Dynamics-CRM-4.0-on-bookshelves-now!.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">3</guid><pubDate>Thu, 18 Dec 2008 00:00:00 GMT</pubDate><category>CRM</category><category>Altriva Info</category><content:encoded><![CDATA[<p>After many hours of work consolidating our combined experience with CRM solutions, our book titled&#160;"<a target="_blank" href="http://www.amazon.com/gp/product/1430216042?ie=UTF8&amp;tag=wwwaltrivacom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1430216042"><u><font color="#810081">Success with Microsoft Dynamics CRM 4.0</font></u></a>" is now available for purchase.&#160;It was written by Altriva founders Aaron Yetter and Justin Mathena with Hoss Hostetler, Director of CRM at Altriva.</p>
<p><a target="_blank" href="http://www.amazon.com/gp/product/1430216042?ie=UTF8&amp;tag=wwwaltrivacom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1430216042"><img border="0" alt="" width="240" height="240" src="/Portals/0/BookCover.jpg" /></a><br />
&#160;<br />
<u><em>Success with Microsoft Dynamics CRM 4.0: Implementing Customer Relationship Management</em></u> is aimed at readers who are interested in understanding how to successfully implement Microsoft Dynamics CRM 4.0 within their projects. It is intended as an implementation roadmap for the business and technical representatives leading or engaged in a project.</p>
<p>The book covers the capabilities of Microsoft Dynamics CRM, both in the traditional functional areas of sales, marketing, and service and as an applications framework for XRM deployments.</p>
<p>The book demonstrates Microsoft CRM best practices for design, configuration, and development. Through real–world solutions and exercises, you will be given the confidence and expertise to deliver an implementation that provides long–term success for your organization.</p>
<p>- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Custom Extensions Discussion - Intro</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/2/Custom-Extensions-Discussion---Intro.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">2</guid><pubDate>Sat, 06 Dec 2008 00:00:00 GMT</pubDate><category>CRM</category><content:encoded><![CDATA[<div>Let's begin our discussion around custom extensions by discussing why they are important and what some of the correct and incorrect approaches are.&#160; We will then have future posts that go into specific Pro’s and Con’s of different custom extensions for Microsoft Dynamics CRM 4.0.</div>
<div>&#160;</div>
<div><b>Custom Extensions Discussion</b></div>
<div>&#160;</div>
<div>Microsoft Dynamics CRM 4.0 is designed to be highly configurable and highly extendable, allowing your company to build a solution to fit your business processes. The base configuration tools within Microsoft Dynamics CRM 4.0 allow your business to closely capture many processes using CRM without any coding or complex configuration. Microsoft Dynamics CRM 4.0 also allows your business to expand business processes and requirements through custom extensions in addition to the configuration tools. This allows your business to incorporate business process facilitation that otherwise could not be captured in CRM, would be cumbersome for users to manually facilitate in a CRM system, or integrate across multiple systems to create one continuous process.</div>
<div>Custom extensions can add value in the following circumstances:&#160;</div>
<ul type="square">
    <li>Your businesses processes do not align with standard SFA/Service/Marketing processes,</li>
    <li>The information users need for certain processes is not or should not be captured within your CRM system,</li>
    <li>The data requirements of your business processes are too complex for a user to manually enter and the potential for automation exists to streamline data entry.</li>
</ul>
<div>It is crucial to understand the extent of what is possible with custom extensions when designing your business' CRM system to ensure better facilitation of your business processes. It is also important to know the pros and cons of implementing a given process using custom extensions versus built in customization tools. Many of the custom extensions and built in tools can accomplish the same goal with different benefits and drawbacks that should be taken into account when designing your custom extensions to facilitate your business processes.</div>
<div>&#160;</div>
<div><b>Incorrect Approaches to Using Custom Extensions</b></div>
<div>&#160;</div>
<div>There are many ways to incorrectly approach the use of custom extensions within Microsoft CRM 4.0. Some incorrect approaches to the custom extensions seen in the market are:</div>
<ul type="square">
    <li>Designing your Microsoft Dynamics CRM 4.0 system without a good understanding of what is possible by leveraging custom extensions to better facilitate your business processes</li>
    <li>Building potentially unnecessary custom extensions without spending adequate time to analyze your business processes</li>
    <li>Building custom extensions for their "coolness factor" alone without making sure it helps facilitate your business process -- if an extension does not help facilitate your business processes then you run the risk of distracting from the real work that needs to happen.</li>
    <li>Favoring one form of custom extension over another due to familiarity with the tool without understanding the benefits and drawbacks in relation to other options to extend Microsoft CRM</li>
    <li>Building an overly complex system that can overwhelm users or not removing unused items till later in your company's CRM evolution when users will need those functions.</li>
</ul>
<div><b>Approaches to doing it right</b></div>
<div>&#160;</div>
<div>The best way to approach the custom extension capabilities of Microsoft Dynamics CRM 4.0 is to first fully understand your business processes, specifically which parts of those processes are causing you pain or costing your business money. The next step is to build those processes into CRM using the base CRM functionality and then re-examining your system to see which pain points remain. Then, with a good working understanding of all the ways you can extend Microsoft CRM, design your custom extensions to relieve the remaining pain points while taking into account the pros and cons of each custom extension approach.</div>
<div>&#160;</div>
<div><b>Comparisons of Different Extension Options</b></div>
<div>&#160;</div>
<div>In the coming weeks we will post some blog entries with a quick comparison of a few of the different custom extension options within Microsoft Dynamics CRM 4.0. We will point out some of the tradeoffs between different options, but we will not compare every aspect or have an exhaustive list of all available custom extension options.&#160; We will add more comparisons as more content is finalized.</div>
<div>We hope to cover the following comparisons in the coming weeks:</div>
<ul type="square">
    <li>&#160;Workflows and Workflow Extensions vs. Plug-ins</li>
    <li>&#160;JavaScript Use&#160;</li>
    <li>&#160;Supported JavaScript vs. Unsupported JavaScript&#160;</li>
    <li>&#160;SiteMap vs. Security</li>
    <li>&#160;Workflows who should vs. who shouldn’t have access</li>
</ul>
<p>- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item><item><title>Welcome</title><link>http://www.altriva.com/AltrivaBlog/tabid/65/PostID/1/Welcome.aspx</link><author>Hoss Hostetler</author><guid isPermaLink="false">1</guid><pubDate>Fri, 05 Dec 2008 00:00:00 GMT</pubDate><category>CRM</category><category>Altriva Info</category><content:encoded><![CDATA[<p>Welcome to the Altriva Team Blog.</p>
<p>Now that we have wrapped up writing our CRM book (Success with Microsoft Dynamics CRM 4.0: Implementing Customer Relationship Management) it is time to move on to publishing some additional content through our website.</p>
<p>Since the book is now complete we needed a place to continue to share our insights and experience for planning, designing, and deploying successful CRM and portal solutions. We hope you find this section of our website helpful to your current and future projects.</p>
<p>In the first few weeks we will discuss how to successfully implement custom extensions within Microsoft Dynamics CRM 4.0 for your organization. We will be looking at how to approach custom extensions to make them the most successful for your organization in your implementation effort of Microsoft Dynamics CRM 4.0.</p>
<p>- Hoss Hostetler</p>]]></content:encoded><trackback:ping /></item></channel></rss>