Sunday, October 11, 2009

CRM 4.0 cloning using entity mapping




In the past I wrote a few posts about cloning an entity using client side scripting. Most of the posts implemented complex script especially to non developers. I wanted to show you a simple cloning technique that leverages CRM built in features and can also work for CRM online.

The benefits of using this technique are:
1. Gain full control over which attributes are cloned
2. Ability to change which attributes are cloned without adding / changing your code.
3. Usage of a very simple script that does not need to be changed when reused.
4. Ability to easily track the parent record from which the cloned entity originated.

Following is the list of built in CRM features I am going to utilize in the post:
1. Creation of CRM form toolbar button
2. Creation of entity relationship.
3. Creation of mapping between related entities.
4. Adding simple script to the cloned entity onload handler.

So how can we actually make the above features work to our advantage. The main feature that lies in the heart of this technique is the ability to create a self referencing relationship between the an entity to itself and use the mapping wizard to tell CRM which attributes we what to pass from the parent record. Once we have that all that remains is to understand how CRM uses the mapping on the client side much like when you create a child contact record from within an account from.

If you take a close look at the URL that is used by CRM when you create a child related record you’ll notice that the URL uses a specific format that tells CRM what is the parent record id and type. Once you learn how to replicate this behavior you’re half way implementing this solution.
The following script which you’ll eventually need to paste in the entity onload event handler shows how to construct the child record or in our case the cloned record url:


Clone = function()
{
var cloneUrl = location.pathname + "?";
cloneUrl += "_CreateFromType=" + crmForm.ObjectTypeCode +
cloneUrl += "&_CreateFromId=" + crmForm.ObjectId +
cloneUrl += "&etc=" + crmForm.ObjectTypeCode + "#";

var cloneFeatures = 'toolbars=0,status=1,width=' + document.body.offsetWidth + "height=" + document.body.offsetHeight;

window.open(cloneUrl,'',cloneFeatures);
}


Once we have the script in place we need to add a toolbar button that will fire the actual cloning process.
Following is a sample clone button xml which you should add to your isv.config


<Entity name="gi_test">
<ToolBar ValidForCreate="0" ValidForUpdate="1">
<Button Icon="/_imgs/ico_18_debug.gif" JavaScript="Clone();">
<Titles>
<Title LCID="1033" Text="Clone" />
</Titles>
<ToolTips>
<ToolTip LCID="1033" Text="Clone" />
</ToolTips>
</Button>
<ToolBarSpacer />
</ToolBar>
</Entity>


Next you’ll need to create a self referencing relationship. To do that open the entity customization and select 1:N relationship. Then select create new relationship. Inside the relationship form choose the same entity on both sides of the relationship. You should select not to display the left navigation link. The bellow image encapsulates the process of creating the self referencing relationship.



Once the relationship is saved you’ll see a mapping link on the relationship form. Select the mapping link to open the mapping wizard.
Add as much mapping as required. Before you publish the entity consider the final step.



Finally, if you wish to track the originating record you only need to add the entity lookup (parent test in this case) that was created as a result of the self referencing relationship. You can also set the lookup field as read only so users can’t change it manually.



That’s it! publish your entity and you’re done.

53 comments:

Vijaya said...

Adi,
I want to implent this clone functionality for a custum entity. Does it works?

Adi Katz said...

This works for customizable and custom entities. The example in the post uses a custom entity called test.

Lucky said...

Hi Adi,
I am very much impressed with this Clone method. I tried it to clone a Quote record. Steps I followed:
1.I created a Quote selfreference relationship and mapped attributes
2. Created a custom Clone Button using ISV config.
3.I added your javascript code on Quote onload event and published the customisations.

I am getting Javascript error on Quote Onload event.
Can you please tell me how to solve this error and attain the functionality.

Adi Katz said...

The process you described sounds right. What error are you getting?

Darren Mercieca said...

Hi Adi, Great Post. I am now attempting to promt the user to enter how may times he would like to clone it, instead of only once. Do you think this is possible? Or do you have any suggestions? Thanks

Lucky said...

Hi Adi,
When I click on Clone button, the page is redirecting CRM error message Window with message 'An error has occurred. try again ..'
Can you please help me.

Adi Katz said...

Darren, you can prompt the user for the number of duplicates and run the onload code x times but I it’s not usable. I suggest letting the user creating a clone out of an existing clone i.e. original  clone1 (new)  clone1(saved)  clone2(new)  clone2(saved)  clone3…

Adi Katz said...

Lucky,

Different entities might require different URLs when creating a child (quote) in a parent (quote) context. I have not tested all , this is just an example. You should create a quote self referencing relationship and create it manually in CRM, then open the child quote and observe its URL. If it’s different from the one the onload code produces you’ll need to make the necessary adjustments in your code.

Anonymous said...

TY for all your extremely useful blog posts!

there seems to be a mistake in the Clone method. ti should read:

Clone = function() {
var cloneUrl = location.pathname + "?";
cloneUrl += "_CreateFromType=" + crmForm.ObjectTypeCode;
cloneUrl += "&_CreateFromId=" + crmForm.ObjectId;
cloneUrl += "&etc=" + crmForm.ObjectTypeCode + "#";

var cloneFeatures = 'toolbars=0,status=1,width=' + document.body.offsetWidth + "height=" + document.body.offsetHeight;

window.open(cloneUrl, '', cloneFeatures);
}

Anonymous said...

Dear Adi,

To start with I placed your ISV code in my ISV config file and imported for the quote entity. I can see the "Clone" button in my VPC but cannot find the button in my test server.
The only difference betwen my VPC and test server is rollup 7 which is not in my vpc.
Kindly advice pls....!

Regards
Prince

Adi Katz said...

By Default the ISV buttons are not shown in the application. You need to change your system settings and refresh the form.

Anonymous said...

Thanx a lot Adi for your generous support, I forgot to enable the ISV config in application mode.

Now I've
1.I created a Quote selfreference relationship and mapped attributes
2. I added your javascript code on Quote onload event as it is and published the customisations

When i click onto the clone button nothing seems to happen. As per the above comments as u said I have to make necessary adjustments in the code which I'm not sure where I've to tweak?
Do I've to add the url of my quote entity in ur code? If yes, the url for
Quote-> http://crm/Contoso/sfa/quotes/edit.aspx?id={863084E1-CDD1-DE11-AE58-0003FFAFD723}#

Quote Detail -> http://crm/Contoso/sfa/quotedetail/edit.aspx?_CreateFromType=1084&_CreateFromId=%7b863084E1-CDD1-DE11-AE58-0003FFAFD723%7d

I dunno wat to add and wat not to? One more thing i noticed is that I've a price list.After adding the code when I click on price list lookup button in quote all my price list has disappeared? I find ur code among all others the most convienient to implement. hence pls advice how to proceed....

Regards
Prince

Anonymous said...

The above code in the comments section for onload event seems to be working.
Using the code above from the comments when I click the clone button another windows is poping up but the page displays " An error has occured...Pls contact microsoft....". Dunno where is the issue??

Matthew said...

Thanks for this Adi, I am also getting "An error has occured...Pls contact microsoft...." when I click on the clone button.

I suspect the URL needs to change in the Onload event depending on whether the Entity is custom or not.
Will continue playing with this.

Paul Bergen said...

Adi - Great way to clone records, thanks.

Would it be a quick addition to fire this on Create? I would like a "Save & Clone" button (similar to the "Save & New" button).

Thanks for all your community support!

Adi Katz said...

Try adding crmForm.Save(); after the window.open call.

Max said...

Hi,

Personally, I had to do this kind of action in the past. However, instead of doing it in JScript, I created a new manual Workflow.

My question is what are the advantages to use a JScript instead of a workflow to clone an entity?

The workflow is configured that way ([xyz] is the entity that you want to clone):
1) Create a new workflow
1.1) Workflow name: Clone [xyz]
1.2) Entity: [xyz]
1.3) Click "OK"
2) Configure the workflow
2.1) Check "On Demand"
2.2) Uncheck everything in the "Start When" section
2.3) Change the scope to "Organization"
2.4) Click "Add Step"
2.4.1) Select "Create Record"
2.4.2) Select [xyz]
2.4.3) Click "Set Properties"
2.4.4) Use the form assistant to put dynamic values
2.4.4.1) Briefly, this is your mapping
2.4.5) Click "Save and close"
2.5) Rename the "Type a step description here." to "Create a copy of the record selected.”
2.6) Click on "Publish"

You can also add some pre-conditions and post-condition to it, but I guess you can understand the possibilities…

If you want to use this new workflow:
1) Go to your [xyz] entity (or use an advanced query)
2) Select all entities that you want to clone
2.1) Click “Run Workflow…”
2.2) Select “Clone [xyz]”
2.3) Click “OK”
2.4) Click “OK”

The “Clone [xyz]” workflow will be executed to all entities selected.

Chris Rogers said...

This is a really nice customization, Adi. Most of the folks citing errors here probably haven't been able to work through the errors in the Clone function definition. Anonymous, on 2009 Oct 24, got close but still missed the ones in the cloneFeatures assignment. Here's my corrected version:


Clone = function()
{
var cloneUrl = location.pathname + "?"
+ "_CreateFromType=" + crmForm.ObjectTypeCode
+ "&_CreateFromId=" + crmForm.ObjectId
+ "&etc=" + crmForm.ObjectTypeCode + "#";

var cloneFeatures = 'toolbars=0,status=1,width=' + document.body.offsetWidth + ',height=' + document.body.offsetHeight;

window.open(cloneUrl,'',cloneFeatures);
}

Adi Katz said...

Thanks Chris! I Appreciate the input.

Carl said...

Hi Adi,

Great sollution. I'd like to make this work to duplucate orders. And as you know: an order can be linked to one or several products. The total ammount of these products will then appear in the order.

Is it possible to not only copy the fields, but also the relationships to the products. So that the same total ammount would appear on the order?

Thanks,

Unknown said...

Hi Can it is possible at the time of cloning opportunity i can also clone the product existing in that opportunity..

If u did this previously then pls guide me ..

mthulisi said...

Hi,
Great Solution.I tried to clone a quoute. This work fine, but i also need to clone the products in the quote so that the two quotes have exactly the same products and totals. Its the same thing with the orders and invoice. How do i do this?Please help?

Unknown said...

This code worked really well on a custom entity. But, I cannot get this to work on a customizable entity. Can this be used on customizable entities? I get a generic CRM error on the window open statement.

Anonymous said...

Hi,
This work fine, but i also need to clone the products in the quote so that the two quotes have exactly the same products and totals. Its the same thing with the orders and invoice. How do i do this?

Thanks,

Anonymous said...

Hi Adi

I have a situation where need to clone parent-child entities with 1:N relation (think Customer with multiple addresses where customer and address are different entities). Need to clone customer but also clone the related addresses. Any help is appreciated.

yeshi said...

Hi Adi
I am very very impressed with your posting very helpful. I am a new MS CRM user, I am suppose to customize a very populated form. with lots of field to collect data. no matter how I arrange the fields the form looks very ugly. I tried the collapsing section or hide/unhide samples you already posted. they did not resolve the issue.
I would like to have a check box (if available in CRM) and based on the check box I want the fields to appear or not appear.Please help if you have any suggestion or any link , that would be very great
Thank you in advance

Shashi said...

Adi, really wonderful customization. Easiest way to clone a record i have seen yet. I have followed the steps posted by you on the load event of form and it's working fine from the record. But when I add the following JavaScript on the menu bar button of an entity it's giving error. It's not uploading the ISV.config file. I have modified the code to work from menu bar of an entity.

"if (crmGrid.InnerGrid.SelectedRecords.length == 1){var typeCode = crmGrid.InnerGrid.SelectedRecords[0][1]; var id = crmGrid.InnerGrid.SelectedRecords[0][0];
var cloneUrl= '/AnnetTechnologies/userdefined/edit.aspx?';
cloneUrl += '_CreateFromType=' + typeCode +'&_CreateFromId=' + id + '&etc=' + typeCode + '#';
var cloneFeatures = 'toolbars=0,status=1,width=600,height= 400';
window.open(cloneUrl,'',cloneFeatures);
}"

Can you tell me how can i clone the record from menu bar button as from the record toolbar button.

Thx,
Shashi

Shashi said...
This comment has been removed by the author.
Shashi said...
This comment has been removed by the author.
Shashi said...

Guys, the error was in the line #3.
cloneUrl += '_CreateFromType=' + typeCode +'&_CreateFromId=' + id + '&etc=' + typeCode + '#';

The preceeding & ampersand sign in the parameter &_CreateFromId= and &etc= should replace with amp&;_CreateFromId= and amp&;_etc=

Sorry for delaying the post.

Thx,
Shashi

Unknown said...

I have used the similar code. It is working absolutely fine.

But recently when I added some attributes to the form I found that when the new copy of the form is opened then all the attributes get added to it,
but values of new attributes are not appearing. could please help me in this regard.

finisterre said...

Any chance of getting this working with hosted CRM 2011?

Can it clone opportunities that are both open and closed?

John Rash said...

CRM software is designed to help businesses meet the overall goals of customer relationship management.

David@crmforbanks

Quickbooks Expert said...

Nice & Informative Blog !
Our team at QuickBooks Technical Support Phone Number 1-877-751-0742 makes sure to provide you with the best technical services for QuickBooks in less time.

Quickbooks Expert said...

Nice & Informative Blog !
QuickBooks is an easy-to-use accounting software that helps you manage all the operations of businesses. In case you want immediate help for QuickBooks issues, call us on QuickBooks Technical Support Phone Number 1-855-974-6537.

AnnaSereno said...

Hey! What a wonderful blog. I loved your blog. QuickBooks is the best accounting software, however, it has lots of bugs like QuickBooks Error. To fix such issues, you can contact experts via QuickBooks technical support number

QuickBooks Support Number said...

Nice & Informative Blog !
Our team at QuickBooks Customer Service makes sure to achieve maximum customer satisfaction in the current circumstances.

Emily Green said...

Hey! Nice Blog, I have been using QuickBooks for a long time. One day, I encountered QuickBooks Customer Service in my software, then I called QuickBooks Error 1328. They resolved my error in the least possible time.

AnnaSereno said...
This comment has been removed by the author.
AnnaSereno said...
This comment has been removed by the author.
Lauren Kathy said...

Hey! What a wonderful blog. I loved your blog. QuickBooks is the best accounting software, however, it has lots of bugs like QuickBooks Error. To fix such issues, you can contact experts via QuickBooks Phone Number

Simmyjessure said...

Nice Blog !! i m so happy After Read Your Blog QuickBooks is best Accounting Software is a perfect tool for managing finances. If you need help Regarding this Software just Call at
quickbooks phone number

Maria Hernandez said...

Hey! Well-written blog. It is the best thing that I have read on the internet today. Moreover, if you are looking for the solution of QuickBooks Software, visit at QuickBooks Customer Service Number (602)325-1557 to get your issues resolved quickly.

QuickBooks Customer Service Phone Number said...

Thanks for sharing such useful information with us. I hope you will share some more info about of QuickBooks for MAC Support . Please keep sharing. We will also provide QuickBooks Support Phone Number (855)746-5668 for instant help.

Quickbooks customer service said...

nice blog. if you are looking forquickbooks customer service you can reach us at.+1 855-444-2233

Quickbooks support Service said...

awesome bolg. if you are looking forquickbook support service. you can contact us at.+1 855-675-3194

quickbooks support service said...

good content. if you are lookinf forQuickbooks Support Phone Number you can contact us at.+18776030806

Jai Jaiswal said...

Good blog. Any thing can control through the powerful yoga so let begin. yogainfo , types of yoga , - theyogainfo.com you reach us at


Quickbooks Support Phone Number.+1 855-769-6757,MD. said...

If you need help on correctable errors or issues on your desktop, call us at Quickbooks Customer Service Phone Number+1 855-769-6757 to get the best services. We are here 24/7 and are ready to provide answers to all your QuickBooks questions.

bu bhopal 1st year result 2022 roll number wise said...

I think this is one of the most significant info for me. And I'm glad reading your article.

Accounting Service said...

very informative blog Thanks for sharing with us please more visit our Quickbooks customer service at my
quickbooks support phone number +1 866-448-6293

Accounting Service said...
This comment has been removed by the author.
bsc 3 year result 2022 said...

whoah, this weblog is excellent I like reading your articles.