<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Abilitics Blog - CRM</title>
    <link>http://blogs.abilitics.com/</link>
    <description />
    <language>en-us</language>
    <copyright>Rossen Zhivkov</copyright>
    <lastBuildDate>Wed, 12 Nov 2008 21:41:43 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>rzhivkov@gmail.com</managingEditor>
    <webMaster>rzhivkov@gmail.com</webMaster>
    <item>
      <trackback:ping>http://blogs.abilitics.com/Trackback.aspx?guid=bbf2fe68-31b5-4c9d-87f0-3213802b4f29</trackback:ping>
      <pingback:server>http://blogs.abilitics.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.abilitics.com/PermaLink,guid,bbf2fe68-31b5-4c9d-87f0-3213802b4f29.aspx</pingback:target>
      <dc:creator>Rossen Zhivkov</dc:creator>
      <wfw:comment>http://blogs.abilitics.com/CommentView,guid,bbf2fe68-31b5-4c9d-87f0-3213802b4f29.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.abilitics.com/SyndicationService.asmx/GetEntryCommentsRss?guid=bbf2fe68-31b5-4c9d-87f0-3213802b4f29</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>
            <font size="3">The scenario: </font>
          </strong>
        </p>
        <p>
One of our current projects required that we had to create a SharePoint list item
(task) when specific condition occurs in CRM - "Responsible person" is selected on
opportunity level. 
</p>
        <p>
          <strong>
            <font size="3">The solution:</font>
          </strong>
        </p>
        <p>
          <strong>1. Create web service on SharePoint Server</strong>
        </p>
        <p>
Often, you will have you SharePoint infrastructure reside on different server than
CRM. Then, you cannot access the object model directly so you need to create a web
serivice. Decide also on service authentication.
</p>
        <p>
In our case - the web service creates an list item (task) in SharePoint, and fills
it with the necessary properties.<br /><br /><strong>2. Create custom workflow activity<br /><br /></strong><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font face="Verdana" size="2">2.1.
Create sharepoint workflow activity library. Add CRM assemblies (from CRM SDK). Annotate
class with appropriate attributes.</font></span></p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[CrmWorkflowActivity(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Crm
Workflow Activity"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"SharePoint
Activity"</span>)] <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> SharePointActivity:
SequenceActivity { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span> SharePointActivity()
   {       InitializeComponent();    }
}</span>
        </pre>
        <p>
2.2. Register dependency properties, which will then be fed from CRM 
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span> DependencyProperty
responsiblePersonProperty <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=<br /></span>   DependencyProperty.Register(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"responsiblePerson"</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>), <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(SharePointActivity));
[CrmInput(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"responsiblePerson"</span>)]
[CrmDefault(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@""</span>)] <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> responsiblePerson
{    get    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>.GetValue(responsiblePersonProperty);
   }    set    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      base</span>.SetValue(responsiblePersonProperty,
value);    }<br />
}</span>
        </pre>
        <p>
2.3. Call the SharePoint web service. For simplicity - no error handling &amp; no
security calling the service.
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext) {    SamsService
sams <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SamsService();
   sams.CreateTask(responsiblePerson); <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   return</span> ActivityExecutionStatus.Closed;
}</span>
        </pre>
        <p>
          <strong>3. Register the custom workflow activity in CRM and enable debugging</strong>
        </p>
        <p>
Registration is pretty straighforward with tools in CRM SDK (plugin registration).
CRM workflows are run "assyncronously" by CRM Assyncronours Service - this means that
in order to debug your custom workflow activites, you need to attach to this service,
not to w3wp. Also,  your code is run with service's credentials  (network
service by default), so you might experience security issues. 
</p>
        <p>
Remember also iisreset &amp; restart assync service on every change<br /></p>
        <p>
          <strong>4. Create CRM workflow that uses the custom activity</strong>
        </p>
        <p>
The workflow is started automatically when opportunity is created. The workflow waits
untill "Reponsible person" is not blank. Then the workllow executes our custom workflow
activity for SharePoint integration, passing all the required properties. 
</p>
        <p>
          <img src="/content/binary/png1.png" width="630" border="0" />
        </p>
        <p>
          <br />
You can pass data from opportunity level, or any related entites such as Primary Contact
or Account to every custom activity's dependency property that has been marked
with the CrmInput attribute.
</p>
        <p>
          <img src="/content/binary/png2.png" width="630" border="0" />
        </p>
        <p>
Sincerely,<br />
Rossen
</p>
        <img width="0" height="0" src="http://blogs.abilitics.com/aggbug.ashx?id=bbf2fe68-31b5-4c9d-87f0-3213802b4f29" />
      </body>
      <title>Integrating CRM 4.0 and SharePoint with Workflows</title>
      <guid isPermaLink="false">http://blogs.abilitics.com/PermaLink,guid,bbf2fe68-31b5-4c9d-87f0-3213802b4f29.aspx</guid>
      <link>http://blogs.abilitics.com/2008/11/12/IntegratingCRM40AndSharePointWithWorkflows.aspx</link>
      <pubDate>Wed, 12 Nov 2008 21:41:43 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;&lt;font size=3&gt;The scenario: &lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
One of our current projects required that we had to create a SharePoint list item
(task) when specific condition occurs in CRM - "Responsible person" is selected on
opportunity level. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=3&gt;The solution:&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;1. Create web service on SharePoint Server&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Often, you will have you SharePoint infrastructure reside on different server than
CRM. Then, you cannot access the object model directly so you need to create a web
serivice. Decide also on service authentication.
&lt;/p&gt;
&lt;p&gt;
In our case - the web service creates an list item (task) in SharePoint, and fills
it with the necessary properties.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;2. Create custom workflow activity&lt;br&gt;
&lt;br&gt;
&lt;/strong&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;2.1.
Create sharepoint workflow activity library. Add CRM assemblies (from CRM SDK). Annotate
class with appropriate attributes.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[CrmWorkflowActivity(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Crm
Workflow Activity"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"SharePoint
Activity"&lt;/span&gt;)] &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; SharePointActivity:
SequenceActivity { &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; SharePointActivity()
&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;InitializeComponent(); &amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
2.2. Register dependency properties, which will then be fed from CRM 
&lt;/p&gt;
&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; DependencyProperty
responsiblePersonProperty &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;DependencyProperty.Register(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"responsiblePerson"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;), &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(SharePointActivity));
[CrmInput(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"responsiblePerson"&lt;/span&gt;)]
[CrmDefault(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@""&lt;/span&gt;)] &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; responsiblePerson
{ &amp;nbsp;&amp;nbsp;&amp;nbsp;get &amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;.GetValue(responsiblePersonProperty);
&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;set &amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base&lt;/span&gt;.SetValue(responsiblePersonProperty,
value); &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
2.3. Call the SharePoint web service. For simplicity - no error handling &amp;amp; no
security calling the service.
&lt;/p&gt;
&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext) { &amp;nbsp;&amp;nbsp;&amp;nbsp;SamsService
sams &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SamsService();
&amp;nbsp;&amp;nbsp;&amp;nbsp;sams.CreateTask(responsiblePerson); &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; ActivityExecutionStatus.Closed;
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;3. Register the custom workflow activity in CRM and enable debugging&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Registration is pretty straighforward with tools in CRM SDK (plugin registration).
CRM workflows are run "assyncronously" by CRM Assyncronours Service - this means that
in order to debug your custom workflow activites, you need to attach to this service,
not to w3wp. Also,&amp;nbsp; your code is run with service's credentials&amp;nbsp; (network
service by default), so you might experience security issues. 
&lt;/p&gt;
&lt;p&gt;
Remember also iisreset &amp;amp; restart assync service on every change&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;4. Create CRM workflow that uses the custom activity&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The workflow is started automatically when opportunity is created. The workflow waits
untill "Reponsible person" is not blank. Then the workllow executes our custom workflow
activity for SharePoint integration, passing all the required properties. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="/content/binary/png1.png" width=630 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
You can pass data from opportunity level, or any related entites such as Primary Contact
or Account to every&amp;nbsp;custom activity's dependency property that has been marked
with the CrmInput attribute.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="/content/binary/png2.png" width=630 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Sincerely,&lt;br&gt;
Rossen
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.abilitics.com/aggbug.ashx?id=bbf2fe68-31b5-4c9d-87f0-3213802b4f29" /&gt;</description>
      <comments>http://blogs.abilitics.com/CommentView,guid,bbf2fe68-31b5-4c9d-87f0-3213802b4f29.aspx</comments>
      <category>CRM</category>
      <category>SharePoint</category>
    </item>
  </channel>
</rss>