Hello Everyone,
I was working on a requirement where i have to clone records on multiple custom entities.if the entity having very less fields, you can achieve it easily but what about those entities where attributes are more than 100 per entity. So, i am going to tell you how you can achieve it easily by writing a very small code.
Lets start!
Step-1: Add a button “Clone” using the ribbon workbench on your entity where you want to perform the cloning. Just drag and drop where you want to add.
Now create a command and add an java script action.
Add java script library and function name(code added below). Add a “Crm Parameter= PrimaryControl”.
After that add the command to the button. Publish the solution from ribbon workbench.
Step-2: Now create a global Action process inside your dynamics solution.and create a input parameter of “Entity” type .
we are going to set it through our java script code as below. So while setting the entity type parameter inside the action, we need to specify two properties , 1) GUID of the record , 2) Logical name in key value pair.
Note: Value you can get easily but how you can make “key” dynamic so that it could run on any custom entity. for that you need to pass the key dynamically as shown in below code(check InvokeAction function parameter).
function callAction(primaryControl) {
debugger;
var formContext=primaryControl;
var formtype = formContext.ui.getFormType();
if(formtype!=1){
debugger;
Xrm.Utility.confirmDialog("Do You want Clone this Record?",
function () {
var recordId = formContext.data.entity.getId().replace("{", "").replace("}", "");
var logicalName = formContext.data.entity.getEntityName();
InvokeAction(recordId,logicalName);
},
function () {});
}
}
function InvokeAction(recordId,logicalName) {
debugger;
var parameters = {};
var target = {};
target[logicalName+"id"]=recordId; //making it dynamics so can be worked on multiple entity
target["@odata.type"] = "Microsoft.Dynamics.CRM."+logicalName;
parameters.Target = target;
var ign_CloneRecordRequest = {
Target: parameters.Target,
getMetadata: function() {
return {
boundParameter: null,
parameterTypes: {
"Target": {
"typeName": "mscrm.crmbaseentity",
"structuralProperty": 5
}
},
operationType: 0,
operationName: "ign_CloneRecord" //specify your action name
};
}
};
Xrm.WebApi.online.execute(ign_CloneRecordRequest).then(
function success(result) {
if (result.ok) {
//Success - No Return Data - Do Something
}
},
function(error) {
Xrm.Utility.alertDialog(error.message);
}
);
}
Step-3:After that you need to create a plugin which will create a clone/copy of the record.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
namespace cloneRecord
{
public class cloneRecord : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);
tracing.Trace(context.InputParameters.Contains("Target").ToString());
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
if(context.Depth>1)
{
return;
}
//Getting the Entity record from the Action
Entity en = (Entity)context.InputParameters["Target"];
//Retrieving the same entity record with all the attributes
Entity entity= service.Retrieve(en.LogicalName, en.Id, new ColumnSet(true));
//Set the EntityState to null, so that a new cloned record can be created
entity.EntityState = null;
//remove the PrimaryId of the record otherwise will show you error
entity.Attributes.Remove(entity.LogicalName+"id") ;
if(entity.Contains("new_name") && (string)entity.Attributes["new_name"]!=string.Empty)
{
//differentiating the new record which will create from the exisiting with New prefix.
entity.Attributes["name"] = "New " + entity.Attributes["name"].ToString();
}
//set a unique id to the cloned record
entity.Id = Guid.NewGuid();
//Create the new cloned record
service.Create(entity);
}
}
}
}
Now register your plugin and use the global action as message inside your plugin step.
Now navigate to custom entity in dynamics model driven app. As you can see here my clone button just click on it.
Now go back to the Entity list record and you will found copied/cloned record as below image. If you want to do cloning of record more than one entity, just follow only the Step-1 as shown above, it will work for any entity.
That’s it.
Hope this will help you. If you having any issues please feel free to ask me . Shoot your question in comment box.