How to Copy
notes/attachments from one Entity to another, when there is a One to Many
relationship exists between them.
To illustrate we have Account
with many Contacts and would like to have all notes n attachment copied from
its parent account when contact is created.
Here are the configuration steps, (workflow code is at the
end)
Step 1) Create a new workflow processes,
so we can call the custom workflow assembly and set its parameter
accordingly.
Step 2) Need to set parameter as
Source Attribute Name : parentcustomerid
Target Entity Name : contact
Demo Steps
Step 1) Create an Account record
and attach file in notes and click save.
Step 2) Create child Contact records and Observe Notes
and attachment gets the attachment from parent account record.
The workflow Code
public sealed class CopyNotesWorkflow : CodeActivity
{
#region
Workflow Parameters
[RequiredArgument]
[Input("Source Attribute Name")]
public InArgument<string> SourceAttributeName {
get; set; }
[RequiredArgument]
[Input("Target Entity
Name")]
public InArgument<string> TargetEntityName { get; set; }
#endregion
Input Parameters
protected override void Execute(CodeActivityContext executionContext)
{
#region
Manage Tracing and Organization Service
// Create the
tracing service
ITracingService tracingService =
executionContext.GetExtension<ITracingService>();
if (tracingService == null)
{
throw new InvalidPluginExecutionException("Failed to retrieve
tracing service.");
}
tracingService.Trace("Entered CopyNotes.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("CopyNotes.Execute(), Correlation Id: {0}, Initiating
User: {1}",
context.CorrelationId,
context.InitiatingUserId);
IOrganizationServiceFactory serviceFactory =
executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService orgService =
serviceFactory.CreateOrganizationService(context.UserId);
#endregion
try
{
var sourceAttribute = this.SourceAttributeName.Get(executionContext);
var targetEntity = this.TargetEntityName.Get(executionContext);
if
(context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity reqResponse = (Entity)context.InputParameters["Target"];
if
(!reqResponse.Attributes.Contains(sourceAttribute))
throw new InvalidPluginExecutionException("Source Relationship
Not found !!!");
var
accountId = ((EntityReference)(reqResponse.Attributes[sourceAttribute])).Id;
// Fetch all Notes and Attachment for associated Leave
Request
QueryExpression Notes = new QueryExpression { EntityName = "annotation", ColumnSet = new ColumnSet(true) };
Notes.Criteria.AddCondition("objectid", ConditionOperator.Equal, accountId);
EntityCollection NotesRetrieve = orgService.RetrieveMultiple(Notes);
if
(NotesRetrieve.Entities.Count > 0)
{
// For all Notes n Attachments retrieved,
loop and create new duplicate notes.
foreach (var
entity in NotesRetrieve.Entities)
{
Entity note = new Entity("annotation");
note["objectid"] = new EntityReference(targetEntity,
reqResponse.Id);
note["objecttypecode"] = targetEntity;// Associate Notes to Request
Response
if (entity.Attributes.Contains("isdocument"))
note["isdocument"] = entity["isdocument"];
if (entity.Attributes.Contains("notetext"))
note["notetext"] = entity["notetext"];
if (entity.Attributes.Contains("filename"))
note["filename"] = entity["filename"];
if (entity.Attributes.Contains("documentbody"))
note["documentbody"] = entity["documentbody"];
if (entity.Attributes.Contains("mimetype"))
note["mimetype"] = entity["mimetype"];
orgService.Create(note);
}
}
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.ToString(), ex);
}
}
}
Thanks.
Vipin Jaiswal
Vipinjaiswal12@gmail.com
8 comments:
Hi Vipin,
The workflow is not working for me.
When on Demand, the workflow shows no error, but the Notes don't get copied over.
When on Create, the workflow throws an error: Source Relationship Not found !!!
Also, I don't understand why you would use the relationship account_primary_contact, as there can only be one per account. So how could notes get copied over all new contacts? This is a N:1 relationship, not a 1:N.
The 1:N relationship between account and contact is contact_customer_accounts, but even with this set as Source Relationship Name, the workflow does not work for me.
Thanks!
Hi Yvan,
I have updated my post after looking at your comments.
The workflow parameter does not require relationship name instead it requires the Relationship Attribute name.
I tried it in my trail instance and now it working like a charm.
Thanks for your post.
Hi Vipin,
Thanks for the update! I just gave this a new try and it's working, but not entirely:)
On create, the workflow works as expecter and all Notes get copied to the child record.
But when I run the workflow on-demand from the contact form, it's does not work. No error message either.
Do you have an idea why?
Hello Yvan,
Can I know if you found any solution for your requirement? I have same requirement to copy existing records to new entity.
Thanks,
Swathi
On Demand Workflow probably doesn't send a Target as Entity which is in source code handled. Add else and throw a new Exception with serialized all names and types of InputParameters and you will know what came :-)
Hi
I'd love to give this a try, but what do I do with the workflow code? Is that a plugin or webresource or...where do I put that?
Many thanks,
Pete.
@Swathi Yes it works fine, but only using in a workflow upon creation. It will not work on-demand, or as a child workflow.
@Anonymous You need to create a custom workflow. There are a lot of tutorials on YoutTube. This will result in a DLL that you need to register in CRM using Plugin Registration Tool.
Post a Comment