Friday, November 4, 2016

Fetch Xml to retrieve N:N Associated records

Below is an example fetch Xml for retrieving the N:N associated records.
Where: 
-N:N exists between entities:  abc_customer  and abc_contract.
-The intersect Entity Name: abc_abc_customer_abc_contract.
-Primary Keys of the abc_customer and the abc_contract are respectively:  abc_customerid and abc_contractid.
-Records to be retrieved from Entity: abc_customer,
fields to retrieve :
abc_fullname, abc_title, abc_telephone1,abc_customerid


"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>"+
  "<entity name='abc_customer'>"+
    "<attribute name='abc_fullname' />"+   
    "<attribute name='abc_title' />"+
    "<attribute name='abc_telephone1' />"+
    "<attribute name='abc_customerid' />"+
    "<order attribute='abc_fullname' descending='false' />"+
    "<link-entity name='abc_abc_customer_abc_contract' from='abc_customerid' to='abc_customerid' visible='false' intersect='true'>"+
      "<link-entity name='abc_contract' from='abc_contractid' to='abc_contractid' alias='aa'>"+
        "<filter type='and'>"+
          "<condition attribute='abc_contractname' operator='eq' value='PensionPlanInsuranceContract' />"+
        "</filter>"+
      "</link-entity>"+
    "</link-entity>"+
  "</entity>"+
"</fetch>"

Similar fetch can be used for retrieving N:N related records with higher depths.

Thursday, November 3, 2016

This record is in multiple queues. Go to the specific queue to view the details

We would have come across this issue several times.

The Cause:
When an entity record in a Queue is deactivated, the corresponding Queeu Item record also is deactivated,
but when the record is Reactivated,  the Queue Item still remains Inactive.

Hence, if you click on Add to Queue on the Record now/Programmatically add this record to a Queue, one more Queue Item is created corresponding to this record.
Implying, now there are 2 Queue Items corresponding to this record, 1 Inactive and other Active.
If  you now click on the Queue Item details, it would throw an error- that record is in multiple Queues.

Solution:
Remove Queue Item from Queue whenever it is deactivated.

Below is the Custom WF to do it.

This can be added as a step in a System WF, with
Primary Entity as Queue Item,  
Trigger: Status Change,  
Condition : If Queue Item:Status equals [Inactive] AND Queue Item:Type equals [<<Your Entity Name>>].
 Parameters to be passed to the custom WF Step : {Record URL(Dynamic)(Object (<<your Entity  type>> ))}


using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using System;
using System.Activities;
namespace Workflow.RemoveQIFRomQueue

{
    public class RemoveQueueItemFromQueue : CodeActivity
    {
        [Input("Queue Item")]
        [ReferenceTarget("queueitem")]
        public InArgument<EntityReference> queueItemReference { get; set; }
        protected override void Execute(CodeActivityContext executionContext)
        {
            #region declare Service related holders
            IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
            IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService _service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = executionContext.GetExtension<ITracingService>();
            #endregion
            EntityReference queueItem = queueItemReference.Get<EntityReference>(executionContext);
            tracingService.Trace("Checking Queue Item Id");
            tracingService.Trace(queueItem.Id.ToString());
            RemoveFromQueueRequest removeFromQueueReq = new RemoveFromQueueRequest()
            {
                QueueItemId = queueItem.Id
            };
            _service.Execute(removeFromQueueReq);
        }
    }
}

Example System WF For removing a  Case - Queue Item from Queue

Sunday, June 19, 2016

Workflow Email Send Issue-"You cannot send email as the selected user. The selected user has not allowed this or you do not have sufficient privileges to do so. Contact your system administrator for assistance."



Ground:
 -A background Workflow  executes in the security context of "the user who runs the WF" when : It is configured as an on-demand process ,And is started by a user using a Run Workflow command

-A background Workflow executes in the security context of "the owner of the workflow" when started based on an event trigger

- For a Real-time workflow  Execute as option decides whether the Workflow Runs in the security context of the owner of the Workflow or the user who runs the workflow.

 (Resource used:https://community.dynamics.com/crm/f/117/t/135682)

Based on the above facts, we can solution the WF in 2 ways:
1) Set a Queue as an Email Sender, this would not need any special permissions for Email Send

2)Else follow the below table
The Analysis Table
Type OF WF
Run As Info
Condition
Solution
Real Time Process
Run As WF Owner
If Sender is other than the Owner, WF fails(Unless special Send As Privilege enabled on Role as well as User Personal Setting done)
Mark the Owner and the Sender of Email as some System User- who has the rights to send Email
Example: 

-WF Owner=CRM Admin
-Mark the Sender too as:CRM Admin
Real Time Process
Run as executing User
If sender is other than the Executing User, WF Fails(Unless special Send As Privilege enabled on Role as well as User Personal Setting done)
-In the WF, have a step to update a hidden flag in the record(revert back at end).

-Mark the Modifed By of the record as the Sender of the Email
(No matter whoever is the Owner of the WF)
Background WF
Runs as Owner of WF
If Sender is other than the Owner, WF fails(Unless special Send As Privilege enabled on Role as well as User Personal Setting done)
Mark the Owner and the Sender of Email as some System User- 
Example: 
-WF Owner=CRM Admin
-Mark the Sender too as:CRM Admin

Dialog
Runs as executing User
If sender is other than the Executing User, WF Fails(Unless special Send As Privilege enabled on Role as well as User Personal Setting done)
 -In the WF, have a step to update a hidden flag in the record(revert back at end).

-Mark the Modifed By of the record as the Sender of the Email
(No matter whoever is the Owner of the WF) 




Another solution that can be applied in all the scenarios:
 Login as a System User say – CRM Admin and make the  below Email settings in the Personal Options by Navigating to - Options-->Email

to allow other Users to send Email on behalf of this User