Thursday, February 11, 2010

Custom workflow action which returns Opportunity Close object based on Opportunity object

All data you've input into the CRM is stored in opportunityclose record when opportunity is closed. And this data is inaccessible from workflow designer because opportunityclose record is child record for opportunity. And I'll try to fix it.



I will made it using custom workflow action. So the code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.Activities;
using Microsoft.Crm.Workflow;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;

namespace OpportunityProductPlugin
{
[CrmWorkflowActivity("Get opportunity close record", "Opportunity utiles")]
public class OpportunityCloseGetter : SequenceActivity
{
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
if (Opportunity != null)
{
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext workflowContext = contextService.Context;
ICrmService crmservice = workflowContext.CreateCrmService();

//Building the query to get opportunity close record
QueryByAttribute query = new QueryByAttribute();
query.Attributes = new string[] { "opportunityid" };
query.ColumnSet = new AllColumns();
query.EntityName = EntityName.opportunityclose.ToString();
query.Values = new object[] { Opportunity.Value };

//Retrieving the data
List<BusinessEntity> entities = crmservice.RetrieveMultiple(query).BusinessEntities;

//Check that opportunity close record exists
if (entities.Count == 1)
{
//Filling output lookup
OpportunityClose = new Lookup(EntityName.opportunityclose.ToString(),((opportunityclose)entities[0]).activityid.Value);
}
}

return ActivityExecutionStatus.Closed;
}

public static DependencyProperty OpportunityProperty = DependencyProperty.Register("Opportunity", typeof(Lookup), typeof(OpportunityCloseGetter));

[CrmInput("Opportunity")]
[CrmReferenceTarget("opportunity")]
public Lookup Opportunity
{
get
{
return (Lookup)base.GetValue(OpportunityProperty);
}
set
{
base.SetValue(OpportunityProperty, value);
}
}

public static DependencyProperty OpportunityCloseProperty = DependencyProperty.Register("OpportunityClose", typeof(Lookup), typeof(OpportunityCloseGetter));

[CrmOutput("OpportunityClose")]
[CrmReferenceTarget("opportunityclose")]
public Lookup OpportunityClose
{
get
{
return (Lookup)base.GetValue(OpportunityCloseProperty);
}
set
{
base.SetValue(OpportunityCloseProperty, value);
}
}

}
}


How to use it - I build simple on-demand workflow:










Source code and ready-to-deploy assembly can be downloaded here.