<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
   <title>stunnware's CRM corner</title>
   <subtitle>Samples and tools for CRM developers</subtitle>
   <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom.aspx" />
   <link rel="alternate" href="http://www.stunnware.com/crm2/default.aspx" />
   <updated>2009-11-30T10:00:00+01:00</updated>
   <author>
      <name>Michael Höhne</name>
   </author>
   <id>urn:uuid:D7C4413D-BD66-4d2e-9E11-587870EFAFE8</id>
   <entry>
      <title>Filtered Views for Microsoft Dynamics CRM 4.0 - v4.2</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=FV4-3" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/FV4-3" />
      <id>tag:stunnware.com,2009-11-30:FV4-3</id>
      <published>2009-11-30T10:00:00+01:00</published>
      <updated>2009-11-30T10:00:00+01:00</updated>
      <content type="html">
   &lt;p&gt;I rarely post about product updates on this blog, but this time I make an 
   exception. The reason is that the new features in the Filtered Views are 
   great and I want to share it with you. &lt;/p&gt;
   &lt;p&gt;So far the Filtered Views allowed creating dynamic views based on 
   parameters being supplied at runtime. With "at runtime" I mean that you pass 
   parameters in your CRM script code. That was good enough to view associated 
   data going well beyond the capabilities of a standard CRM view. However, good 
   is never good enough, so here's the list of enhancements in the new release:&lt;/p&gt;
   &lt;ol&gt;
	   &lt;li&gt;UI Filters to define custom search fields in filtered views&lt;/li&gt;
	   &lt;li&gt;Multi-Language support&lt;/li&gt;
	   &lt;li&gt;An entity context to activate field mappings when creating a new 
	   entity from a filtered view&lt;/li&gt;
	   &lt;li&gt;Script support to perform typical tasks like hiding toolbar buttons 
	   or colorizing views&lt;/li&gt;
   &lt;/ol&gt;
   &lt;p&gt;Probably the best explanation of what you can do with these new features 
   is the following screenshot: &lt;/p&gt;
   &lt;p&gt;&lt;img height="293" src="images/FV-3/ColorsAndParameters.png" width="644"&gt;&lt;/p&gt;
    </content>
   </entry>
   <entry>
      <title>Stunnware Tools for Microsoft Dynamics CRM 4.0 - Support for CRM Online</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=Framework14" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/Framework14" />
      <id>tag:stunnware.com,2009-10-02:Framework14</id>
      <published>2009-10-02T22:00:00+01:00</published>
      <updated>2009-10-02T22:00:00+01:00</updated>
      <content type="html">
&lt;p&gt;I was asked yesterday whether support for CRM Online was planned for the
&lt;a href="http://www.stunnware.com/default.aspx?area=products&amp;group=swtools4&amp;subarea=swtools4-overview"&gt;
Stunnware Tools&lt;/a&gt; and the
&lt;a href="http://www.stunnware.com/default.aspx?area=products&amp;group=jsf4&amp;subarea=jsf4-overview"&gt;
JavaScript Factory&lt;/a&gt;. My answer was that it hasn't been implemented just 
because I never had access to CRM Online. That was a minor issue though, because 
I instantly got credentials to a test organization and even admin rights for 
testing. That was great and it turned out that having a framework combining a 
set of tools was a good decision, because once I had the code implemented to use 
the passport and CRM Online services, all tools started working instantly.&lt;/p&gt;
&lt;p&gt;I had added support for the offline services recently and now the Stunnware 
Tools support anything: On-Premise, Partner Hosted (IFD), CRM Online and the 
Outlook Offline client. If I have implemented the automatic version check 
correctly and you haven't turned it off, then you may already be aware of the 
new release before having read this post. &lt;/p&gt;
&lt;p&gt;The new version is available for download at
&lt;a href="http://www.stunnware.com/default.aspx?area=products&amp;group=swtools4&amp;subarea=swtools4-download"&gt;
http://www.stunnware.com/default.aspx?area=products&amp;group=swtools4&amp;subarea=swtools4-download&lt;/a&gt;.&lt;/p&gt;    </content>
   </entry>
   <entry>
      <title>Client Side Scripting - Converting date/time values to or from XML</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=JS36" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/JS36" />
      <id>tag:stunnware.com,2009-09-29:JS36</id>
      <published>2009-09-29T23:00:00+01:00</published>
      <updated>2009-09-29T23:00:00+01:00</updated>
      <content type="html">
Being a mystery in the beginning it's now common knowledge how to use the CRM web services in CRM form scripts. However, there were two questions recently dealing with date fields. Date values in XML are notated in a way that you probably know from your .NET code, 2008-03-12T13:55:46+01:00 for instance. The .NET DateTime object can easily handle it, but the JavaScript Date object cannot. The Filtered Lookup of course supports date fields in queries and I implemented appropriate conversion methods. Feel free to use them.
    </content>
   </entry>
   <entry>
      <title>Client Side Scripting - Customer Products</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=JS35" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/JS35" />
      <id>tag:stunnware.com,2009-09-28:JS35</id>
      <published>2009-09-28T17:00:00+01:00</published>
      <updated>2009-11-09T17:00:00+01:00</updated>
      <content type="html">
There was an interesting thread in the CRM developer 
   newsgroups recently. Assume that you have built your product catalog and use 
   CRM to create opportunities, quotes, orders and invoices, or at least some of 
   these entities. All of them refer to the products in your product catalog. 
   Now consider your customers. If they order products from your company 
   regularly, then they most likely store your products in their own system. 
   However, they will use their own product numbers to refer to your products 
   and when ordering they will tell you these product numbers and not yours. &lt;/p&gt;
   &lt;p class="normal"&gt;The question was how to enable a user to search for a 
   product using both the internal product number and the external product 
   number, where with "external" I mean the product number used by the customer. &lt;/p&gt;
   &lt;p class="normal"&gt;An easy solution is adding a custom attribute to the 
   product entity, but of course you can then only store one product number. 
   This approach doesn't work when dealing with multiple customers, unless you 
   like having a product number field for each customer. As each product can 
   have many customer product numbers, the solution is a customer product entity 
   and a 1:n relationship between products and customer products:&lt;/p&gt;
    </content>
   </entry>
   <entry>
      <title>The JavaScript Factory</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=JavaScriptFactory" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/JavaScriptFactory" />
      <id>tag:stunnware.com,2009-09-15:JavaScriptFactory</id>
      <published>2009-09-15T15:00:00+01:00</published>
      <updated>2009-09-15T15:00:00+01:00</updated>
      <content type="html">
&lt;p&gt;As mentioned in the last article published a few minutes ago I 
			had some work to do in the recent months. New major releases of the 
			Filtered Lookup, which now supports multi-select lookup fields, the 
			Filtered Views, Favorite Views and finally the JavaScript Factory.&lt;/p&gt;
&lt;p class="productheader"&gt;JavaScript Factory&lt;/p&gt;
&lt;p&gt;&lt;img height="354" src="../../Products/JSF4/images/Product.png" style="float: right" width="608"&gt;Most readers of this blog certainly are developers and most are developing 
CRM solutions. One part of CRM development are form scripts and my personal 
feeling is that many if not the majority of developers are still using the CRM 
 editor to write script code.&lt;/p&gt;
			&lt;p&gt;This editor is a simple text box without any added functionality and while acceptable for smaller code changes it’s a real pain when working with larger code files.
&lt;/p&gt;
			&lt;p&gt;A simple workaround is to copy the code from the CRM code window 
			into a JavaScript file in Visual Studio 2008. Visual Studio 2008 has 
			IntelliSense support for JavaScript and at least provides help for 
			the objects of the document object model (DOM). However, as Visual 
			Studio 2008 doesn’t know about CRM, it cannot provide IntelliSense 
			for CRM-specific objects.&lt;/p&gt;
			&lt;p&gt;Furthermore you cannot split large files into modules easily. It 
			is possible to dynamically load JavaScript libraries into CRM forms, 
			but managing such libraries is a manual step. &lt;/p&gt;
			&lt;p&gt;For developers using Microsoft technologies it's usually a 
			no-brainer to use Visual Studio and developing CRM form scripts 
			shouldn't be different. If you search the Internet for articles on 
			how to edit form scripts in Visual Studio then you will find some 
			and if they are sufficient for you then you're done. Anyone else is 
			welcome to have a closer look at the JavaScript Factory, which 
			provides the following features:&lt;/p&gt;
			&lt;ul&gt;
				&lt;li&gt;Creates a Visual Studio Solution for any CRM 
				organization, extracts the JavaScript code and enables direct 
				editing in Visual Studio 2008.&lt;/li&gt;
				&lt;li&gt;Merges the OnLoad, OnChange and OnSave event handlers 
				into a single file for easier editing.&lt;/li&gt;
				&lt;li&gt;Allows multiple source files for each entity.&lt;/li&gt;
				&lt;li&gt;Provides IntelliSense support for the entire CRM form object 
				model, including custom entities and attributes.&lt;/li&gt;
				&lt;li&gt;Saves and publishes changes directly from Visual Studio 
				2008.&lt;/li&gt;
				&lt;li&gt;Updates existing solutions with updated customizations.&lt;/li&gt;
				&lt;li&gt;Starts full create and update forms directly from Visual 
				Studio 2008.&lt;/li&gt;
				&lt;li&gt;Manages organization-specific and -unspecific JavaScript 
				libraries. &lt;/li&gt;
				&lt;li&gt;Builds the form script by compiling the form code and all 
				referenced libraries. As a result you have a single script file 
				in CRM, but can have dozens or even hundreds of modules 
				containing these files.&lt;/li&gt;
				&lt;li&gt;Because of the file-based solution approach you can use 
				version control systems to manage your code.&lt;/li&gt;
				&lt;li&gt;Supports On-Premise and IFD setups.&lt;/li&gt;
			&lt;/ul&gt;
			&lt;p&gt;That's just the Visual Studio part. The CRM JavaScript Factory for Microsoft Dynamics CRM 4.0 
			is a server-side module that can be used to support developer teams:&lt;/p&gt;
			&lt;ul&gt;
				&lt;li&gt;Builds CRM form scripts on the fly without having to publish 
				changes. &lt;/li&gt;
				&lt;li&gt;Enables developers to edit the script code and to take full 
				advantage of the library management and IntelliSense support, 
				even without the CRM JavaScript Factory for Visual Studio 2008.&lt;/li&gt;
			&lt;/ul&gt;
			&lt;p&gt;The server component is code-complete but documentation isn't 
			finished yet. Won't take long to complete though. If you are 
			interested in this solution then go to the
			&lt;a href="/default.aspx?area=products&amp;group=jsf4"&gt;product page&lt;/a&gt; 
			and download the documentation to get a first impression. The 
			product page also contains information about how to obtain an 
			evaluation license, in case you want to try it out.&lt;/p&gt;
</content>
   </entry>
   <entry>
      <title>The CRM 4.0 Metadata Cache - Part 2</title>
      <link rel="alternate" type="text/html" href="http://www.stunnware.com/crm2/topic.aspx?id=MetadataCache2" />
      <link rel="self" type="application/atom+xml" href="http://www.stunnware.com/crm2/atom/MetadataCache2" />
      <id>tag:stunnware.com,2009-09-15:MetadataCache2</id>
      <published>2009-09-15T14:00:00+01:00</published>
      <updated>2009-09-15T14:00:00+01:00</updated>
      <content type="html">
As I had some work to do recently it took much longer to complete this 
article, though the implementation was finished a long time ago. I have attached 
the code to this article and you can download it by clicking the download button 
in the top left corner. &lt;/p&gt;
&lt;p&gt;The implementation uses two main classes, the CrmOrganizationMetadataCache 
and the CrmMetadataCache. CrmOrganizationMetadataCache is used to cache the 
metadata of one organization. CrmMetadataCache manages multiple organization 
caches, which is a requirement for any solution supporting multi-tenancy. &lt;/p&gt;
&lt;p&gt;The implementation supports a variety of options. I included a wish list in 
the previous article:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;It must provide an organizational cache.&lt;/li&gt;
	&lt;li&gt;It must be capable to deal with multiple organizations to support 
	multi-tenancy.&lt;/li&gt;
	&lt;li&gt;It should give a choice between read-all-at-once and a lazy-loading 
	approach.&lt;/li&gt;
	&lt;li&gt;It should never request more data than needed. For instance, if you 
	request an entity with attributes and relationships and the attributes were 
	already retrieved, then only relationships will be loaded and the result is 
	merged into the existing cache.&lt;/li&gt;
	&lt;li&gt;It must be thread-safe. This is very important for server-side 
	applications, where multiple users will call your code in parallel. The 
	cache will be defined as a static member in your implementation, but static 
	members are not thread-safe by default. Intelligent synchronizing of 
	requests is important for a good performance.&lt;/li&gt;
	&lt;li&gt;It must have methods to persist itself. Saving a cache to disk and 
	loading it when the application starts again is much faster than requesting 
	the data from CRM again.&lt;/li&gt;
	&lt;li&gt;It must have the ability to check for updated metadata and to clear the 
	cache if the metadata was changed. As this is not required by all 
	applications, appropriate settings have to be available.&lt;/li&gt;
	&lt;li&gt;Helper classes must exists for easy language management, though this can 
	be implemented at various places. A short explanation: when reading the 
	metadata you are running under a certain user account. This user account (systemuser) 
	is used by CRM to retrieve the user's language settings. All UserLocLabel 
	properties in the returned metadata contain the localized labels for this 
	user. When you cache the metadata and simply user UserLocLabel to access 
	display names, then all users using a different language will be somewhat 
	disappointed. Instead of using UserLocLabel you have extract the appropriate 
	label from the LocLabel collection. For that to work you need to retrieve 
	the user settings first and use the language settings as an argument into 
	the LocLabels array. It isn't too complex, but worth to be put into a helper 
	class. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the exception of the last item in the list all features are available. &lt;/p&gt;
&lt;p&gt;I cannot guarantee that the code is free of errors and I also don't say that 
it's perfect. But I added a lot of comments to make it easy to understand. Feel 
free to use and enhance it.    </content>
   </entry>
</feed>