Monday 30 January 2012

Customising RetrieveMulitple Request

I was working on a task where I was creating a dialog, this dialog shows list of records in a drop down control and once I select a value in drop down and then enter some value in the text box, I apply the formula for the value enter for the selected record, also on the form user is asked if he want to do the task again for another record. Selecting Yes recrusivly calls the same dialog and exclude the one which i have already applied formulla on.

Solution:
To achieve this on the custom entity create a filter attribute and add some string to differenciate the request which needs to be changed.
e.g. new_retrievemultiplefilter

In dialog create a crm queury and pass all the neccesary conditions along with the specified attribute with the value e.g. "custom entity needs custom filter"



Plugin: CustomEntityRetrieveMulitple
Stage: Pre transaction


IOrganizationService crmService = localContext.OrganizationService;

            object query = localContext.PluginExecutionContext.InputParameters["Query"];
            if (query.GetType() == typeof(FetchExpression))
            {
                FetchExpression fe = (FetchExpression)localContext.PluginExecutionContext.InputParameters["Query"];
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(fe.Query);

                XmlNode retrievemultiplefilterCondtion = doc.SelectSingleNode("fetch/entity/filter/condition[@attribute='new_retrievemultiplefilter']");

                if (retrievemultiplefilterCondtion != null)
                {
                    string value = retrievemultiplefilterCondtion.Attributes["value"].Value;
                    if (string.Equals(value, " custom entity needs custom filter ", StringComparison.InvariantCultureIgnoreCase))
                    {
                        XmlNode retrievemultiplefilterNode = retrievemultiplefilterCondtion.ParentNode;
                        retrievemultiplefilterNode.RemoveChild(retrievemultiplefilterCondtion);

                        XmlNode impCondition1 = doc.SelectSingleNode("fetch/entity/link-entity/filter/condition[@attribute='new_value1']");
                        XmlNode impCondition2 = doc.SelectSingleNode("fetch/entity/link-entity/filter/condition[@attribute=' new_value2']");
                     
                        string val1= null, val2 = null;

                        if ( impCondition1  != null && stepIdCondition != null)
                        {
                            val1=  impCondition1.Attributes["value"].Value;
                            val2 =  impCondition2 .Attributes["value"].Value;
                        }

                        XmlNode  new_customentity2Node = doc.SelectSingleNode("fetch/entity/link-entity[@name='new_customentity2']");

                        XmlNode entityNode =  new_customentity2Node.ParentNode;
                        entityNode.RemoveChild( new_customentity2Node );

                        EntityCollection records = Utility.GetFilteredRecords(crmService, val1,val2);
                        if (records.Entities.Count > 0)
                        {
                            XmlNode notInCondition = doc.CreateNode(retrievemultiplefilterCondtion.NodeType, retrievemultiplefilterCondtion.Name, retrievemultiplefilterCondtion.NamespaceURI);
                            XmlAttribute attribute = doc.CreateAttribute("attribute");
                            attribute.Value = "new_customid";
                            notInCondition.Attributes.Append(attribute);

                            XmlAttribute operatorAttribute = doc.CreateAttribute("operator");
                            operatorAttribute.Value = "not-in";
                            notInCondition.Attributes.Append(operatorAttribute);

                            retrievemultiplefilterNode.AppendChild( notInCondition );

                            foreach (var  record  in  records  .Entities)
                            {
                                XmlNode valueNode = doc.CreateNode(retrievemultiplefilterNode.NodeType, "value", retrievemultiplefilterNode.NamespaceURI);
                                valueNode.InnerText = ((EntityReference) record  ["new_customid"]).Id.ToString();
                                 notInCondition .AppendChild( valueNode  );                              
                            }
                        }
                        localContext.PluginExecutionContext.InputParameters["Query"] = new FetchExpression(doc.OuterXml);
                    }
                }
            }

Cannot set a value on node type 'Element'

Message: Cannot set a value on node type 'Element'

Solution: instead of using node.Value = "dummy value" use node.innerText = "dummy value"

Friday 27 January 2012

Creating workflow activity

Use CRM Development toolkit
and Select "New Visual Studio Solution Template for Dynamics CRM 2011"

add following references if not already added
Microsoft.Xrm.Sdk, Microsoft.Xrm.Sdk.Workflow, System.Runtime.Serialization
System.Activities, System.Activites.Presentation

Sign the assembly, and click deploy, In case you don't see custom activity/ updated field/ updated behaviour then ResetIIS


public class CustomActivity: CodeActivity
    {
        protected override void Execute(CodeActivityContext codeActivityContext)
        {
            IWorkflowContext workflowContext = codeActivityContext.GetExtension<IWorkflowContext>();
            EntityReference entityReference = new EntityReference
            {
                Id = workflowContext.PrimaryEntityId,
                LogicalName = workflowContext.PrimaryEntityName
            };

            IExecutionContext context = codeActivityContext.GetExtension<IExecutionContext>();
            IOrganizationServiceFactory serviceFactory = codeActivityContext.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);


            Entity entity = service.Retrieve(entityReference.LogicalName, entityReference.Id, new ColumnSet(new string[] { "new_attribute1", "new_attribute2", "new_attribute3" }));

            EntityReference Lookup = (EntityReference)stepInstance[" new_attribute1"];

            Entity entity2= service.Retrieve(Lookup.LogicalName, Lookup.Id, new ColumnSet(new string[] { "new_attribute1" }));
            int maxStageDurationDays = (int) entity2 [" new_attribute1"];

             int numberOfDays = NumberOfDays.Get(codeActivityContext);
           //some calculations...
                DaysExceeded.Set(codeActivityContext, totalDays);
        }

        [Output("Days Exceeded")]
        public OutArgument<int> DaysExceeded { get; set; }
       
        [RequiredArgument]
        [Input("Number Of Days")]
        public InArgument<int> NumberOfDays { get; set; }
    }


http://luckyabhishek.blogspot.com/2010/12/crm-2011-beta-creating-workflow.html

http://andreaswijayablog.blogspot.com/2011/09/crm-2011-custom-workflow-activity-send.html

Thursday 26 January 2012

newly created attribute is not shown on form and dialog

I have created and publish an attribute, placed it on form, however when I was trying to set it on dialog I don't see it present on form at all. Even when I opened the entity record the attribute was not there.

Resolution: IISReset

Sunday 22 January 2012

How To Use "ValueRule" and "OrRule" in Ribbon Customizations - CRM 2011

http://howto-mscrm.blogspot.com/2011/04/how-to-series-5-how-to-use-valuerule.html


---

When using value rule for the 'Two Options' the ribbon button was not behaving as expected i.e. always stays hidden.

Reason:

Value of the two options field should be only used in 1 or 0
 

Monday 9 January 2012

you do not have sufficient privileges to view this chart. Contact your system administrator

When done a new installation and created a new users and assigned them system administrator role. When logged in with the new user I am getting "you do not have sufficient privileges to view this chart. Contact your system administrator" message.

Resolution: Open the user and change the "Access Mode" from administrator to read-write and "licence type" to Full.