public void When_a_request_is_for_non_existing_queueitem_an_exception_is_thrown() { var context = new XrmFakedContext(); var service = context.GetOrganizationService(); var user = new Entity { LogicalName = Crm.SystemUser.EntityLogicalName, Id = Guid.NewGuid(), }; context.Initialize(new[] { user }); var executor = new PickFromQueueRequestExecutor(); var req = new PickFromQueueRequest { QueueItemId = Guid.NewGuid(), WorkerId = user.Id, }; Assert.Throws <FaultException <OrganizationServiceFault> >(() => executor.Execute(req, context)); }
public void When_a_request_is_called_worker_is_set() { var context = new XrmFakedContext(); var service = context.GetOrganizationService(); var email = new Entity { LogicalName = Crm.Email.EntityLogicalName, Id = Guid.NewGuid(), }; var queue = new Entity { LogicalName = Crm.Queue.EntityLogicalName, Id = Guid.NewGuid(), }; var user = new Entity { LogicalName = Crm.SystemUser.EntityLogicalName, Id = Guid.NewGuid(), }; var queueItem = new Entity { LogicalName = Crm.QueueItem.EntityLogicalName, Id = Guid.NewGuid(), Attributes = { { "queueid", queue.ToEntityReference() }, { "objectid", email.ToEntityReference() } } }; context.Initialize(new[] { queue, email, user, queueItem }); var executor = new PickFromQueueRequestExecutor(); var req = new PickFromQueueRequest { QueueItemId = queueItem.Id, WorkerId = user.Id, }; var before = DateTime.Now.Ticks; executor.Execute(req, context); var after = DateTime.Now.Ticks; var queueItemUpdated = service.Retrieve(Crm.QueueItem.EntityLogicalName, queueItem.Id, new ColumnSet(true)); Assert.Equal(user.ToEntityReference(), queueItemUpdated.GetAttributeValue <EntityReference>("workerid")); Assert.True(before <= queueItemUpdated.GetAttributeValue <DateTime>("workeridmodifiedon").Ticks); Assert.True(after >= queueItemUpdated.GetAttributeValue <DateTime>("workeridmodifiedon").Ticks); }
/// <summary> /// This method first connects to the Organization service. /// Initiate method to create any entity records that this sample requires. /// Retrieves new owner's details. /// Update the queue item record to assign it to new owner. /// Optionally delete any entity records that were created for this sample. /// <para name="organizationFriendlyName">The friendly name of the /// target organization.</para> /// <para name="discoveryServer">The name of the discovery server.</para> /// <param name="promptForDelete">Indicates whether to prompt the user to /// delete the records created in this sample.</param> /// </summary> public void Run(ServerConnection.Configuration serverConfig, bool promptForDelete) { try { // Connect to the Organization service. // The using statement assures that the service proxy will be properly disposed. using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri, serverConfig.Credentials, serverConfig.DeviceCredentials)) { // This statement is required to enable early-bound type support. _serviceProxy.EnableProxyTypes(); // Call the method to create any data that this sample requires. CreateRequiredRecords(); //<snippetAssignQueueItemWorker1> // Retrieve the current user information. WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); WhoAmIResponse whoAmIResponse = (WhoAmIResponse)_serviceProxy.Execute( whoAmIRequest); ColumnSet columnSet = new ColumnSet("fullname"); SystemUser currentUser = (SystemUser)_serviceProxy.Retrieve( SystemUser.EntityLogicalName, whoAmIResponse.UserId, columnSet); String currentUserName = currentUser.FullName; _userId = currentUser.Id; // Create an instance of an existing queueitem in order to specify // the user that will be working on it using PickFromQueueRequest. PickFromQueueRequest pickFromQueueRequest = new PickFromQueueRequest { QueueItemId = _queueItemId, WorkerId = _userId }; _serviceProxy.Execute(pickFromQueueRequest); //</snippetAssignQueueItemWorker1> Console.WriteLine("The letter queue item is queued for new owner {0}.", currentUserName); DeleteRequiredRecords(promptForDelete); } } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ) { // You can handle an exception here or pass it back to the calling method. throw; } }
public void When_a_request_is_called_with_removal_queueitem_is_deleted() { var context = new XrmFakedContext(); var service = context.GetOrganizationService(); var email = new Entity { LogicalName = Crm.Email.EntityLogicalName, Id = Guid.NewGuid(), }; var queue = new Entity { LogicalName = Crm.Queue.EntityLogicalName, Id = Guid.NewGuid(), }; var user = new Entity { LogicalName = Crm.SystemUser.EntityLogicalName, Id = Guid.NewGuid(), }; var queueItem = new Entity { LogicalName = Crm.QueueItem.EntityLogicalName, Id = Guid.NewGuid(), Attributes = { { "queueid", queue.ToEntityReference() }, { "objectid", email.ToEntityReference() } } }; context.Initialize(new[] { queue, email, user, queueItem }); var executor = new PickFromQueueRequestExecutor(); var req = new PickFromQueueRequest { QueueItemId = queueItem.Id, WorkerId = user.Id, RemoveQueueItem = true }; executor.Execute(req, context); Assert.Empty(context.Data[Crm.QueueItem.EntityLogicalName]); }
/// <summary> /// Pick item from <c>Queue</c> to <c>System User</c>. /// <para> /// For more information look at https://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.pickfromqueuerequest(v=crm.7).aspx /// </para> /// </summary> /// <param name="queueItemId"><c>Queue</c> Id</param> /// <param name="systemuserId"><c>System User</c> Id</param> /// <param name="shouldRemoved">Set <c>true</c>, if you want remove item from Queue. Otherwise set <c>false</c> </param> /// <returns> /// <see cref="PickFromQueueResponse"/> /// </returns> public PickFromQueueResponse PickFromQueue(Guid queueItemId, Guid systemuserId, bool shouldRemoved = false) { ExceptionThrow.IfGuidEmpty(queueItemId, "queueItemId"); ExceptionThrow.IfGuidEmpty(systemuserId, "systemuserId"); PickFromQueueRequest request = new PickFromQueueRequest() { QueueItemId = queueItemId, RemoveQueueItem = shouldRemoved, WorkerId = systemuserId }; return((PickFromQueueResponse)this.OrganizationService.Execute(request)); }
public void When_a_request_is_for_non_existing_woker_an_exception_is_thrown() { var context = new XrmFakedContext(); var service = context.GetOrganizationService(); var queue = new Entity { LogicalName = Crm.Queue.EntityLogicalName, Id = Guid.NewGuid(), }; var queueItem = new Entity { LogicalName = Crm.QueueItem.EntityLogicalName, Id = Guid.NewGuid(), Attributes = { { "queueid", queue.ToEntityReference() }, { "objectid", Guid.NewGuid() } } }; context.Initialize(new[] { queue, queueItem }); var executor = new PickFromQueueRequestExecutor(); var req = new PickFromQueueRequest { QueueItemId = queueItem.Id, WorkerId = Guid.NewGuid(), }; Assert.Throws <FaultException <OrganizationServiceFault> >(() => executor.Execute(req, context)); }
[STAThread] // Added to support UX static void Main(string[] args) { CrmServiceClient service = null; try { service = SampleHelpers.Connect("Connect"); if (service.IsReady) { #region Sample Code ////////////////////////////////////////////// #region Set up SetUpSample(service); #endregion Set up #region Demonstrate // Retrieve the current user information. WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); WhoAmIResponse whoAmIResponse = (WhoAmIResponse)service.Execute( whoAmIRequest); ColumnSet columnSet = new ColumnSet("fullname"); SystemUser currentUser = (SystemUser)service.Retrieve( SystemUser.EntityLogicalName, whoAmIResponse.UserId, columnSet); String currentUserName = currentUser.FullName; _userId = currentUser.Id; // Create an instance of an existing queueitem in order to specify // the user that will be working on it using PickFromQueueRequest. PickFromQueueRequest pickFromQueueRequest = new PickFromQueueRequest { QueueItemId = _queueItemId, WorkerId = _userId }; service.Execute(pickFromQueueRequest); Console.WriteLine("The letter queue item is queued for new owner {0}.", currentUserName); #region Clean up CleanUpSample(service); #endregion Clean up } #endregion Demonstrate #endregion Sample Code else { const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Dynamics CRM"; if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR)) { Console.WriteLine("Check the connection string values in cds/App.config."); throw new Exception(service.LastCrmError); } else { throw service.LastCrmException; } } } catch (Exception ex) { SampleHelpers.HandleException(ex); } finally { if (service != null) { service.Dispose(); } Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } }
/// <summary> /// Executes the workflow activity. /// </summary> /// <param name="executionContext">The execution context.</param> protected override void Execute(CodeActivityContext executionContext) { // Create the tracing service ITracingService tracingService = executionContext.GetExtension <ITracingService>(); if (tracingService == null) { throw new InvalidPluginExecutionException("Failed to retrieve tracing service."); } tracingService.Trace("Entered " + _processName + ".Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}", executionContext.ActivityInstanceId, executionContext.WorkflowInstanceId); // Create the context IWorkflowContext context = executionContext.GetExtension <IWorkflowContext>(); if (context == null) { throw new InvalidPluginExecutionException("Failed to retrieve workflow context."); } tracingService.Trace(_processName + ".Execute(), Correlation Id: {0}, Initiating User: {1}", context.CorrelationId, context.InitiatingUserId); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); tracingService.Trace("entering 'try'", ""); try { tracingService.Trace("building fetch", ""); string fetchXml = @"<fetch distinct='false' mapping='logical' output-format='xml-platform' version='1.0'> <entity name='queueitem'> <attribute name='title'/> <attribute name='enteredon'/> <attribute name='objecttypecode'/> <attribute name='objectid'/> <attribute name='queueid'/> <attribute name='workerid'/> <order descending='false' attribute='enteredon'/> <filter type='and'> <condition attribute='statecode' value='0' operator='eq'/> <condition attribute='objecttypecode' value='112' operator='eq'/> <condition attribute='queueid' value='{0}' operator='eq'/> <condition attribute='workerid' operator='null'/> </filter> <link-entity name='incident' alias='casealias' link-type='inner' to='objectid' from='incidentid'> <attribute name='prioritycode'/> <attribute name='ticketnumber'/> </link-entity> </entity> </fetch> "; Guid queueId = Queue.Get(executionContext).Id; fetchXml = string.Format(fetchXml, queueId); tracingService.Trace("prepared fetchxml: {0}", fetchXml); tracingService.Trace("retrieving queue items", ""); EntityCollection queueItems = service.RetrieveMultiple(new FetchExpression(fetchXml)); tracingService.Trace("instantiating empty queueitem", ""); Entity item = new Entity("queueitem"); string caseNumber = ""; string caseTitle = ""; string caseId = Guid.Empty.ToString(); bool caseFound = false; if (queueItems.Entities.Count > 0) { caseFound = true; tracingService.Trace("processing queueitems", ""); item = queueItems.Entities[0]; tracingService.Trace("objectid: {0}", ((EntityReference)item["objectid"]).Id); caseId = ((EntityReference)item["objectid"]).Id.ToString(); caseTitle = item["title"].ToString(); caseNumber = ((AliasedValue)item["casealias.ticketnumber"]).Value.ToString(); if (Assign.Get(executionContext)) { tracingService.Trace("processing assignment", ""); PickFromQueueRequest request = new PickFromQueueRequest(); request.RemoveQueueItem = RemoveFromQueue.Get(executionContext); request.QueueItemId = item.Id; request.WorkerId = User.Get(executionContext).Id; service.Execute(request); } } tracingService.Trace("setting outputs", ""); CaseId.Set(executionContext, caseId); CaseNumber.Set(executionContext, caseNumber); CaseTitle.Set(executionContext, caseTitle); CaseFound.Set(executionContext, caseFound); } catch (FaultException <OrganizationServiceFault> e) { tracingService.Trace("Exception: {0}", e.ToString()); // Handle the exception. throw; } catch (Exception e) { tracingService.Trace("Exception: {0}", e.ToString()); throw; } tracingService.Trace("Exiting " + _processName + ".Execute(), Correlation Id: {0}", context.CorrelationId); }
protected override void Execute(CodeActivityContext executionContext) { #region "Load CRM Service from context" Common objCommon = new Common(executionContext); objCommon.tracingService.Trace("Load CRM Service from context --- OK"); #endregion #region "Read Parameters" EntityReference sourceQueue = this.SourceQueue.Get(executionContext); objCommon.tracingService.Trace(String.Format("sourceQueue: {0} ", sourceQueue.Id.ToString())); bool removeItems = this.RemoveItems.Get(executionContext); objCommon.tracingService.Trace(String.Format("removeItems: {0} ", removeItems.ToString())); int quantity = this.Quantity.Get(executionContext); objCommon.tracingService.Trace(String.Format("quantity: {0} ", quantity.ToString())); #endregion //query for retrieving all the queueitems from one queue StringBuilder sFetchXML = new StringBuilder(@" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'> <entity name='queueitem'> <attribute name='enteredon' /> <attribute name='objecttypecode' /> <attribute name='objectid' /> <attribute name='queueid' /> <order attribute='enteredon' descending='true' /> <filter type='and'> <condition attribute='statecode' operator='eq' value='0' /> <condition attribute='workerid' operator='null' /> <condition attribute='queueid' operator='eq' uitype='queue' value='" + sourceQueue.Id.ToString() + @"' /> </filter> </entity> </fetch>"); objCommon.tracingService.Trace(String.Format("FetchXML: {0} ", sFetchXML.ToString())); EntityCollection queueItems = objCommon.service.RetrieveMultiple(new FetchExpression(sFetchXML.ToString())); if (queueItems.Entities.Count == 0) { //no pending queuitems return; } int count = 0; foreach (Entity queItem in queueItems.Entities) { //pick from Queue PickFromQueueRequest pickFromQueueRequest = new PickFromQueueRequest { QueueItemId = queItem.Id, WorkerId = objCommon.context.InitiatingUserId, RemoveQueueItem = removeItems }; objCommon.service.Execute(pickFromQueueRequest); count++; if (count >= quantity) { //only pick the defined Quantity break; } } }
/// <summary> /// This method first connects to the Organization service. /// Initiate method to create any entity records that this sample requires. /// Retrieves new owner's details. /// Update the queue item record to assign it to new owner. /// Optionally delete any entity records that were created for this sample. /// <para name="organizationFriendlyName">The friendly name of the /// target organization.</para> /// <para name="discoveryServer">The name of the discovery server.</para> /// <param name="promptForDelete">Indicates whether to prompt the user to /// delete the records created in this sample.</param> /// </summary> public void Run(ServerConnection.Configuration serverConfig, bool promptForDelete) { try { // Connect to the Organization service. // The using statement assures that the service proxy will be properly disposed. using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri, serverConfig.Credentials, serverConfig.DeviceCredentials)) { // This statement is required to enable early-bound type support. _serviceProxy.EnableProxyTypes(); // Call the method to create any data that this sample requires. CreateRequiredRecords(); //<snippetAssignQueueItemWorker1> // Retrieve the current user information. WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); WhoAmIResponse whoAmIResponse = (WhoAmIResponse)_serviceProxy.Execute( whoAmIRequest); ColumnSet columnSet = new ColumnSet("fullname"); SystemUser currentUser = (SystemUser)_serviceProxy.Retrieve( SystemUser.EntityLogicalName, whoAmIResponse.UserId, columnSet); String currentUserName = currentUser.FullName; _userId = currentUser.Id; // Create an instance of an existing queueitem in order to specify // the user that will be working on it using PickFromQueueRequest. PickFromQueueRequest pickFromQueueRequest = new PickFromQueueRequest { QueueItemId = _queueItemId, WorkerId = _userId }; _serviceProxy.Execute(pickFromQueueRequest); //</snippetAssignQueueItemWorker1> Console.WriteLine("The letter queue item is queued for new owner {0}.", currentUserName); DeleteRequiredRecords(promptForDelete); } } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>) { // You can handle an exception here or pass it back to the calling method. throw; } }
/// <summary> /// Function ensure that the given Queue Item is set to use a Team Queue /// and sets the Worked By to the user if the queue item was originall set using a user's default queue /// </summary> /// <param name="executionContext">Code activity execution context</param> /// <param name="crmWorkflowContext">Contains the organisation service and trace service</param> public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext) { // Validation if (crmWorkflowContext == null) { throw new ArgumentNullException(nameof(crmWorkflowContext)); } // 1. Get the Queue currently set for the Queue Item we are interested in EntityReference queueItemEntityReference = QueueItemEntityReference.Get(executionContext); Entity queueItem = GetQueueItem(crmWorkflowContext, queueItemEntityReference); EntityReference queue = queueItem[Model.QueueItem.Queue] as EntityReference; if (queue == null) { // There is no queue, nothing to do here. return; } // 2. Get the user that has this Queue as a Default Queue var user = GetUserForQueue(crmWorkflowContext, queue); // 3. If we have a user, it means we need to switch the queue item to use a team queue if (user != null) { if (!user.Attributes.ContainsKey(Model.User.DefaultTeamQueue)) { // The user does not have a default team queue set, cannot change to use a team queue return; } var queueToUse = user[Model.User.DefaultTeamQueue] as EntityReference; var target = queueItem[Model.QueueItem.Target] as EntityReference; // Is there no default team queue set-up for the user? if (queueToUse == null) { // No default team queue means we can't change the queue, nothing to do here return; } // Move a record from a source queue to a destination queue // by using the AddToQueue request message. AddToQueueRequest routeRequest = new AddToQueueRequest { SourceQueueId = queue.Id, Target = target, DestinationQueueId = queueToUse.Id }; crmWorkflowContext.OrganizationService.Execute(routeRequest); // 4. And finally, set the worked on for the queueitem to be the user. // Create an instance of an existing queueitem in order to specify // the user that will be working on it using PickFromQueueRequest. PickFromQueueRequest pickFromQueueRequest = new PickFromQueueRequest { QueueItemId = queueItem.Id, WorkerId = user.Id }; crmWorkflowContext.OrganizationService.Execute(pickFromQueueRequest); } }
/// <summary> /// Executes the workflow activity. /// </summary> /// <param name="executionContext">The execution context.</param> protected override void Execute(CodeActivityContext executionContext) { // Create the tracing service ITracingService tracingService = executionContext.GetExtension<ITracingService>(); if (tracingService == null) { throw new InvalidPluginExecutionException("Failed to retrieve tracing service."); } tracingService.Trace("Entered " + _processName + ".Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}", executionContext.ActivityInstanceId, executionContext.WorkflowInstanceId); // Create the context IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>(); if (context == null) { throw new InvalidPluginExecutionException("Failed to retrieve workflow context."); } tracingService.Trace(_processName + ".Execute(), Correlation Id: {0}, Initiating User: {1}", context.CorrelationId, context.InitiatingUserId); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); tracingService.Trace("entering 'try'", ""); try { tracingService.Trace("building fetch", ""); string fetchXml = @"<fetch distinct='false' mapping='logical' output-format='xml-platform' version='1.0'> <entity name='queueitem'> <attribute name='title'/> <attribute name='enteredon'/> <attribute name='objecttypecode'/> <attribute name='objectid'/> <attribute name='queueid'/> <attribute name='workerid'/> <order descending='false' attribute='enteredon'/> <filter type='and'> <condition attribute='statecode' value='0' operator='eq'/> <condition attribute='objecttypecode' value='112' operator='eq'/> <condition attribute='queueid' value='{0}' operator='eq'/> <condition attribute='workerid' operator='null'/> </filter> <link-entity name='incident' alias='casealias' link-type='inner' to='objectid' from='incidentid'> <attribute name='prioritycode'/> <attribute name='ticketnumber'/> </link-entity> </entity> </fetch> "; Guid queueId = Queue.Get(executionContext).Id; fetchXml = string.Format(fetchXml, queueId); tracingService.Trace("prepared fetchxml: {0}", fetchXml); tracingService.Trace("retrieving queue items", ""); EntityCollection queueItems = service.RetrieveMultiple(new FetchExpression(fetchXml)); tracingService.Trace("instantiating empty queueitem", ""); Entity item = new Entity("queueitem"); string caseNumber = ""; string caseTitle = ""; string caseId = Guid.Empty.ToString(); bool caseFound = false; if (queueItems.Entities.Count > 0) { caseFound = true; tracingService.Trace("processing queueitems", ""); item = queueItems.Entities[0]; tracingService.Trace("objectid: {0}", ((EntityReference)item["objectid"]).Id); caseId = ((EntityReference)item["objectid"]).Id.ToString(); caseTitle = item["title"].ToString(); caseNumber = ((AliasedValue)item["casealias.ticketnumber"]).Value.ToString(); if (Assign.Get(executionContext)) { tracingService.Trace("processing assignment", ""); PickFromQueueRequest request = new PickFromQueueRequest(); request.RemoveQueueItem = RemoveFromQueue.Get(executionContext); request.QueueItemId = item.Id; request.WorkerId = User.Get(executionContext).Id; service.Execute(request); } } tracingService.Trace("setting outputs", ""); CaseId.Set(executionContext, caseId); CaseNumber.Set(executionContext, caseNumber); CaseTitle.Set(executionContext, caseTitle); CaseFound.Set(executionContext, caseFound); } catch (FaultException<OrganizationServiceFault> e) { tracingService.Trace("Exception: {0}", e.ToString()); // Handle the exception. throw; } catch (Exception e) { tracingService.Trace("Exception: {0}", e.ToString()); throw; } tracingService.Trace("Exiting " + _processName + ".Execute(), Correlation Id: {0}", context.CorrelationId); }