locked
CRM4: Move Activities with xRM Advanced Developer? RRS feed

  • Question

  • I am using the xRM advanced developer extensions in CRM4 to move old cases/incidents to an archived entity.  When I move/copy the case over, I also want to then repoint all the related activities to the new entity record.  I have some code here to loop through the activities and change the regardingobjectid to the new record, but it doesn't seem to work?  The activities don't get moved.

    public static int MoveActivities(Guid ExistingCaseGUID, Guid CaseArchiveGUID, CRMConnections crmc, Globals g)
    {
     int ActivitiesMoved = 0;
     var ActivitestoMove = (from a in crmc.CrmDataContext.tasks
      where a.regardingobjectid.Value == ExistingCaseGUID
      orderby a.createdon
      select a).ToList();
     foreach (var act in ActivitestoMove)
     {
      act.regardingobjectid.Value = CaseArchiveGUID;
      act.regardingobjectid.Type = "custom_casearchive";
      ActivitiesMoved++;
     }
     crmc.CrmDataContext.SaveChanges();
     return ActivitiesMoved;
    }
    

     

     

    Monday, June 20, 2011 4:11 PM

Answers

  • I tried this too, but it didn't work. 

    crmc.CrmDataContext.UpdateObject(act);

    However, I then went back and used the old school SDK method of service.execute after setting new values and discovered what the problem was.  The activities were all 'completed' because the cases were closed.  You can't update the activity because it's now set to 'read-only'.

    So I wrote some code that would set the activity back to open, reset the regardingobject, then close it again.  Not the most elegant way, but it works.

    QueryExpression query = new QueryExpression("task");
    query.ColumnSet = new ColumnSet(new string[] { "activityid", "regardingobjectid", "statecode", "statuscode" });
    query.Criteria = new FilterExpression();
    query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, ExistingCaseGUID.ToString());
    // query.Criteria.AddCondition("statecode", ConditionOperator.Equal, new object[] { 0 });
    RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
    retrieve.Query = query;
    retrieve.ReturnDynamicEntities = true;
    	
    RetrieveMultipleResponse retrievedActivities = crmc.CrmDataContext.UsingService(service => (RetrieveMultipleResponse)service.Execute(retrieve));
    if (retrievedActivities.BusinessEntityCollection.BusinessEntities.Count > 0)
    {
    	foreach (DynamicEntity retrievedActivity in retrievedActivities.BusinessEntityCollection.BusinessEntities)
    	{
    		Utilities.OutputToConsole(g, "Moving Activity [" + ((Key)retrievedActivity["activityid"]).Value.ToString() + "]");
    	// DynamicEntity retrievedActivity = (DynamicEntity)retrievedActivities.BusinessEntityCollection.BusinessEntities[0];
    
    		string ti = retrievedActivity["statecode"].ToString();
    		int currentStatus = ((Status)retrievedActivity["statuscode"]).Value;
    
    		if (ti == "Completed")
    		{
    			SetStateTaskRequest taskRequest = new SetStateTaskRequest();
    			taskRequest.EntityId = ((Key)retrievedActivity["activityid"]).Value;
    			taskRequest.TaskState = TaskState.Open;
    			taskRequest.TaskStatus = 3;
    			crmc.CrmDataContext.UsingService(service => service.Execute(taskRequest));
    		}
    
    		((Lookup)retrievedActivity["regardingobjectid"]).Value = CaseArchiveGUID;
    		((Lookup)retrievedActivity["regardingobjectid"]).type = "custom_casearchive";
    		((Status)retrievedActivity["statuscode"]).Value = 3;
    		crmc.CrmDataContext.UsingService(service => service.Update(retrievedActivity));
    
    		if (ti == "Completed")
    		{
    			SetStateTaskRequest taskRequest = new SetStateTaskRequest();
    			taskRequest.EntityId = ((Key)retrievedActivity["activityid"]).Value;
    			taskRequest.TaskState = TaskState.Completed;
    			taskRequest.TaskStatus = currentStatus;
    			crmc.CrmDataContext.UsingService(service => service.Execute(taskRequest));
    		}
    		ActivitiesMoved++;
    	}
    
    	if (ActivitiesMoved != 0)
    		Utilities.OutputToConsole(g, "Moved [" + ActivitiesMoved.ToString() + "] Activities...");
    
    }
    else
    	Utilities.OutputToConsole(g, "No Activities Moved......");
    

     

    • Marked as answer by ChrisH5491 Tuesday, June 21, 2011 12:00 PM
    Tuesday, June 21, 2011 12:00 PM

All replies

  • I believe you need to set regardingobjecttypecode property if you want to attach the existing activity record to a different entity.
    Daniel Cai | http://danielcai.blogspot.com
    Monday, June 20, 2011 6:55 PM
  • Note that you should mind the case to be used for the property, since I used lower case.

    EDIT: Never mind, CRM4 is ok with lower case.


    Daniel Cai | http://danielcai.blogspot.com

    Monday, June 20, 2011 6:57 PM
  • To the OP; you'll also need to .UpdateObject() the record(s) before calling .SaveChanges():

     

    foreach (var act in ActivitestoMove)
    {
    	act.regardingobjectid.Value = new Guid();
    	act.regardingobjectid.Type = "custom_casearchive";
    
    	crmc.CrmDataContext.UpdateObject(act);
    ActivitiesMoved++; }


     


    --pogo (pat) @ pogo69.wordpress.com
    • Proposed as answer by David Withers Tuesday, June 21, 2011 6:04 AM
    Tuesday, June 21, 2011 3:18 AM
  • pogo has made a good point, you might need to incorporate both changes. I am relatively sure that you need to set regardingobjecttypecode in order to attach an existing activity record to a different entity.

    Cheers,


    Daniel Cai | http://danielcai.blogspot.com
    Tuesday, June 21, 2011 5:13 AM
  • Isn't there another way to do it?

    So in your instance you'd:

     

    custom_casearchive CustomCaseArchive = new custom_casearchive();
    CustomCaseArchive.regardingobjectid = new Guid(GuidVariable);

     

     

     

        private void assign_owner2(CrmService CRM, SecurityPrincipal assignee, string accountid)
        {
    
          TargetOwnedAccount target = new TargetOwnedAccount();
    
          target.EntityId = new Guid(accountid); //GUID of account to be re-assigned
    
          AssignRequest assign = new AssignRequest();
    
          assign.Assignee = assignee;
          assign.Target = target;
    
          AssignResponse assignResponse = (AssignResponse)CRM.Execute(assign);
        }
    


     


    David Withers
    Tuesday, June 21, 2011 6:30 AM
  • I tried this too, but it didn't work. 

    crmc.CrmDataContext.UpdateObject(act);

    However, I then went back and used the old school SDK method of service.execute after setting new values and discovered what the problem was.  The activities were all 'completed' because the cases were closed.  You can't update the activity because it's now set to 'read-only'.

    So I wrote some code that would set the activity back to open, reset the regardingobject, then close it again.  Not the most elegant way, but it works.

    QueryExpression query = new QueryExpression("task");
    query.ColumnSet = new ColumnSet(new string[] { "activityid", "regardingobjectid", "statecode", "statuscode" });
    query.Criteria = new FilterExpression();
    query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, ExistingCaseGUID.ToString());
    // query.Criteria.AddCondition("statecode", ConditionOperator.Equal, new object[] { 0 });
    RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
    retrieve.Query = query;
    retrieve.ReturnDynamicEntities = true;
    	
    RetrieveMultipleResponse retrievedActivities = crmc.CrmDataContext.UsingService(service => (RetrieveMultipleResponse)service.Execute(retrieve));
    if (retrievedActivities.BusinessEntityCollection.BusinessEntities.Count > 0)
    {
    	foreach (DynamicEntity retrievedActivity in retrievedActivities.BusinessEntityCollection.BusinessEntities)
    	{
    		Utilities.OutputToConsole(g, "Moving Activity [" + ((Key)retrievedActivity["activityid"]).Value.ToString() + "]");
    	// DynamicEntity retrievedActivity = (DynamicEntity)retrievedActivities.BusinessEntityCollection.BusinessEntities[0];
    
    		string ti = retrievedActivity["statecode"].ToString();
    		int currentStatus = ((Status)retrievedActivity["statuscode"]).Value;
    
    		if (ti == "Completed")
    		{
    			SetStateTaskRequest taskRequest = new SetStateTaskRequest();
    			taskRequest.EntityId = ((Key)retrievedActivity["activityid"]).Value;
    			taskRequest.TaskState = TaskState.Open;
    			taskRequest.TaskStatus = 3;
    			crmc.CrmDataContext.UsingService(service => service.Execute(taskRequest));
    		}
    
    		((Lookup)retrievedActivity["regardingobjectid"]).Value = CaseArchiveGUID;
    		((Lookup)retrievedActivity["regardingobjectid"]).type = "custom_casearchive";
    		((Status)retrievedActivity["statuscode"]).Value = 3;
    		crmc.CrmDataContext.UsingService(service => service.Update(retrievedActivity));
    
    		if (ti == "Completed")
    		{
    			SetStateTaskRequest taskRequest = new SetStateTaskRequest();
    			taskRequest.EntityId = ((Key)retrievedActivity["activityid"]).Value;
    			taskRequest.TaskState = TaskState.Completed;
    			taskRequest.TaskStatus = currentStatus;
    			crmc.CrmDataContext.UsingService(service => service.Execute(taskRequest));
    		}
    		ActivitiesMoved++;
    	}
    
    	if (ActivitiesMoved != 0)
    		Utilities.OutputToConsole(g, "Moved [" + ActivitiesMoved.ToString() + "] Activities...");
    
    }
    else
    	Utilities.OutputToConsole(g, "No Activities Moved......");
    

     

    • Marked as answer by ChrisH5491 Tuesday, June 21, 2011 12:00 PM
    Tuesday, June 21, 2011 12:00 PM
  • This is interesting to know. Thanks for sharing. 
    Daniel Cai | http://danielcai.blogspot.com
    Tuesday, June 21, 2011 1:38 PM