To update notes (annotations) added to a Contact and replicate them to the associated Account in Dynamics 365, you can use Power Automate or a plugin. Here's a step-by-step guide for both approaches:
Option 1: Using Power Automate
This is a no-code/low-code solution.
Steps:
1. Create a Power Automate Flow:
Navigate to PowerApps portal and create a new automated flow.
2. Trigger: When a Note is Created:
Use the trigger "When a row is added, modified, or deleted".
Select the Annotation (Note) entity as the table.
3. Add a Condition: Check the Regarding Field:
Add a condition to ensure the Regarding (regardingobjectid) field is linked to a Contact:
Expression: @equals(triggerOutputs()?['body/_regardingobjectid_type'], 'contacts')
4. Retrieve the Contact's Related Account:
Use the Get a row by ID action to retrieve the Contact.
Table name: Contacts
Row ID: triggerOutputs()?['body/_regardingobjectid_value']
Extract the Contact's associated Account (_parentcustomerid_value).
5. Create a Note on the Account:
Add the Add a new row action:
Table name: Annotation (Notes).
Fields:
Regarding: Set this to the Account's ID.
Note Title: Copy the title from the Contact's Note.
Value: triggerOutputs()?['body/subject']
Note Text: Copy the content of the note.
Value: triggerOutputs()?['body/notetext'].
6. Save and Test the Flow:
Save the flow and test it by creating a new note on a Contact.
Option 2: Using a Plugin
This approach offers more control and flexibility but requires C# development.
Steps:
1. Create a Plugin Project:
Use the Plugin Registration Tool and create a new plugin project in Visual Studio.
2. Register the Plugin on Create of Annotation:
Target the Annotation entity.
Set the plugin to trigger on the Create message in the PostOperation stage.
3. Plugin Code: Below is an example of the C# code:
public class SyncNotesToAccount : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the tracing service
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity note = (Entity)context.InputParameters["Target"];
// Check if the note is linked to a Contact
if (note.Attributes.Contains("objecttypecode") &&
(string)note.Attributes["objecttypecode"] == "contact")
{
// Retrieve the Contact's Account
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Guid contactId = ((EntityReference)note["objectid"]).Id;
Entity contact = service.Retrieve("contact", contactId, new ColumnSet("parentcustomerid"));
if (contact.Attributes.Contains("parentcustomerid"))
{
EntityReference accountRef = (EntityReference)contact["parentcustomerid"];
// Create a new note on the Account
Entity accountNote = new Entity("annotation");
accountNote["subject"] = note.Contains("subject") ? note["subject"] : string.Empty;
accountNote["notetext"] = note.Contains("notetext") ? note["notetext"] : string.Empty;
accountNote["objectid"] = accountRef;
accountNote["objecttypecode"] = "account";
service.Create(accountNote);
}
}
}
}
}
4. Register and Deploy the Plugin:
Use the Plugin Registration Tool to register and deploy the plugin to the Create event of the Annotation entity.