Fun with JScript – Cloning a Case aka How do I have a "Master" Case with Microsoft CRM 3


So recently on one of our internal discussion aliases, somebody asked about how to have a master case with a number of “sub-cases.” This is handy when you have a number of issues like a service outage or patch that doesn’t quite apply as desired. J


So in thinking about the problem, I cheated… In class 8525A, we have a tutorial that teaches you how to Clone a Contact. After thinking about it for a few minutes, what is really the business issue? So you want the ability to create a number of cases quickly and tie them all back to a master case.


So to meet this need, here where a few things I did to give you an idea how to do you could do this for a customer. Again, this is inspiration, not a step by step instruction manual. I would better term this as “Demo Ware.” Your actual mileage may vary. Code is available below in the attachments area. (Or clicking here.



Picture of Master Case



Picture of Cloned Case




  1. Create Two Fields

    1. One called NewMasterCase, which will be a Bit Field
    2. One called New_MasterTicketNumber, which is a nvar 100 field.

  2. Add the two fields to the case form. I would make the bit field a check box and the case number should be disabled.
  3. Open the Web.Config File and change the ISV Config portion to “All”.
  4. Copy the enclosed ISV.Config to the C:\Program Files\Microsoft CRM Server\CRMWeb\_Resources\ directory. (I am assuming you are using the demo VPC, if not, your actual directory may differ.)

    1. If you already have modified your ISV.Config file, just change yours with the Incident Entity. (Assuming again that if you have a modified ISV Config, you have a clue what you are doing. J)

  5. Copy the CloneCase.htm file to C:\Program Files\Microsoft CRM Server\CRMWeb\CloneCase\ Directory. (You may have to create the CloneCase Directory.)
  6. Publish Changes.

Now this should work out of the box. If you have additional fields and you want to modify this and you don’t want to read the comments, here is a line:


new_masterticketnumber.DataValue = oSource.ticketnumber.DataValue;


So in this case new_masterticketnumber is the field on the cloned case, where as oSource.ticketnumber.DataValue is the original case field. (So if you wanted the Title field to be copied, that line would look like:


title.DataValue = oSource.title.DataValue;


If you don’t a field mapped, simply comment that line out with “//” which will remove the field from the mappings.


This code will not work as is. You HAVE to create those two fields otherwise, you will get an error message.


This could also be handy in cloning quotes, opportunities, products and much more. What uses could you see for it?


Enjoy!   


 


April 11th Update – Added Matt’s Changes below

CloneCase.zip

Comments (65)

  1. Thanks, Ben. Nice example. I added a line to the javascript that goes back and sets the "Master Case?" bit field to true so that once you’ve cloned a case it automatically updates the master case:

    oSource.new_mastercase.DataValue = true;

    I also added some text to the title of the new case so I could tell that it had been cloned from another case:

    title.DataValue = (oSource.title.DataValue + " **CLONED**");

    This is the kind of customization and extending that makes CRM 3.0 so much fun to work with 😉 It really opens up a lot of potential for client-side functionality.

  2. Ben Vollmer says:

    Matt,

    Thanks so much… I love this part of CRM… Have you gotten through the book yet? Chapter 10 is turning out to be my favorite… Except it is about 100 pages too short… :-)

    I updated the attachment to reflect the code changes you suggested. :-)

    Thanks!

    Ben

  3. Aby says:

    Hi,

    Can we also add a view in the details area of a case "you know under information " and we name that view related cases . So when we have a master case and a number of related cases that all refer to that master case we can view them all from that related cases view?

  4. Ben Vollmer says:

    You can. I would do a personal view with a where the master case number equals whatever value you want. It probably wouldn’t take but a minute or two to do that…

  5. shisom says:

    Great info! Could you do the same with an activity? I can’t figure out how to add the button to the task or email interface?

  6. Ben Vollmer says:

    I would look at the SDK… Those areas should be available at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/CrmSdk3_0/htm/v3d0customizingmicrosoftcrm2005.asp

    i haven’t looked at it in details, but you can get to pretty much every area in CRM with the ISV.Config file.

  7. Aby says:

    OK having the clone button is a great idea , but sometimes the master case is created after the incidents . I mean some problems happen and we get some cases opened in CRM, then we discover that all those were caused by one master problem. So we need a way to have it the other way around , so in that case we need a field that says this case is related to the master case number bla bla bla. Which means we will need a field of a lookup type which will get all master cases for us to choose from.

    The problem i faced was that the only way "i know" to create a lookup type field is by creating a new entity and then creating a relationship between that entity and the case entity. Is there a way to create a relationship between cases and cases so I can lookup master cases from any case ?

    A bit confusing hah? ;p

    Aby

  8. Ben Vollmer says:

    You could create the Master Case ID as a hyerlink instead of a number…. That would allow you to do that… You could also create a linker entity and do it that way as well.

    Like this: http://blogs.msdn.com/midatlanticcrm/archive/2006/02/17/Many_to_Many_in_Microsoft_CRM_3_Opportunity_Accounts.aspx

    The scenario this was designed for was a very simple one. :-) Given more time and more complex requirements, this could be much more complex. :-)

  9. Aby says:

    To open an edit form, we specify the object ID as in the SDK example To open an edit form, specify the object ID:

    http://crmserver/SFA/accts/edit.aspx?id={1F8B6FC0-426A-4122-BAC2-A05B6071FC57}

    if i try using the case title it will open a new for with the title i specified. Is there a way to use the title ?

  10. Aby says:

    One last question, how did you use a checkbox for the master case?

    As in the forms there are only option buttons "yes or no"

  11. Ben Vollmer says:

    When you add it to the form, you have the choice to make it radio buttons, a picklist or check box. :-)

  12. Aby says:

    Thanx i didn’t notice that .. because i found some ppl saying in a group that it has to be done by creating your own ASP page bla bla bla ..thanx again :)

  13. Steve says:

    Hi,

    Is there any way to modify this code so that it can create multiple copies of a given case?

    I’ve tried adding a field called "no of cases" and then created a loop in the code which takes in the number entered in this field and loops through the code that number of times but after it’s created the first copy and closed/saved it, it then loads up a second blank case form but doesn’t copy any data onto it and the code seems to stop at that point.

    Does anyone have any ideas or am I just trying to do something that’s not possible in this way?

    Thanks, Steve

  14. Ben Vollmer says:

    Steve,

    It may be possible. Seeing how you would just have to click the button twice for two cases and three times for three cases, I never put much thought into it. I don’t think just looping it will work though.

    Thanks

    Ben

  15. Steve says:

    Thanks – we’re trying to develop it so you can enter a number of cases and a frequency and then when you click a button it will create x number of copies, altering the date on each one depending on the frequency selected.

    Ie: You could select 10 recurrencies at a weekly interval or 12 at monthly intervals.

    The client we’re working with often provides regular recurring services for it’s clients and wants a quick way of adding each recurrence as a seperate case.

    They want to be able to just add the details once on the master case, click the button then leave it to create the copies and enter the needed dates on it’s own without any further interaction.

    If I manage to figure it out from modifying this code I’ll post back the code incase if it’d be of any interest to anyone here.

  16. steves2k5 says:

    I’ve managed to get it working quite nicely for creating multiple copies of a case from the master case.

    Steps to do this are exactly the same as the original description above except you need to add a 3rd custome field to the case form with the schema name ‘new_totalcases’.

    <script language=”javascript”>

    //Copyright 2006 Microsoft Corporation
    //All Rights Reserved
    //Provided As-Is with no support

    //Multiple duplication code added by Steve Strang, July 2006. stephens@cooperparry.com

    function window.onload()
    {
    var oClonedCase;
    var count;
    var totalnew;
    var testpage;
    var grandtotal;

    count = 0;
    totalnew = window.dialogArguments.document.crmForm.new_totalcases.DataValue;
    grandtotal = totalnew;
    totalnew=totalnew-1;

    for(count=0; count<totalnew; count++)
    {
    // Open a new case form
    oClonedCase = window.open(‘/cs/cases/edit.aspx’,count,’menubar=0, status=1, width=1000, height=600′);
    testpage = 0;
    while(testpage==0)
    {
    if (oClonedCase.document.readyState == ‘complete’)
    {
    testpage=1;
    }
    }

    // Get a pointer to the parent window
    var oParent = window.dialogArguments;
    var oSource = oParent.document.crmForm;

    //Set the Master Case to True to allow for ease of searching
    oSource.new_mastercase.DataValue = true;

    oClonedCase.document.crmForm.title.DataValue = oSource.title.DataValue;
    oClonedCase.document.crmForm.subjectid.DataValue = oSource.subjectid.DataValue;
    oClonedCase.document.crmForm.caseorigincode.DataValue = oSource.caseorigincode.DataValue;
    oClonedCase.document.crmForm.casetypecode.DataValue = oSource.casetypecode.DataValue;
    oClonedCase.document.crmForm.customersatisfactioncode.DataValue = oSource.customersatisfactioncode.DataValue;
    oClonedCase.document.crmForm.customerid.DataValue = oSource.customerid.DataValue;
    oClonedCase.document.crmForm.statuscode.DataValue = oSource.statuscode.DataValue;
    oClonedCase.document.crmForm.prioritycode.DataValue = oSource.prioritycode.DataValue;
    oClonedCase.document.crmForm.productserialnumber.DataValue = oSource.productserialnumber.DataValue;

    // Master Case
    oClonedCase.document.crmForm.new_masterticketnumber.DataValue = oSource.ticketnumber.DataValue;
    oClonedCase.document.crmForm.SaveAndClose();

    }
    alert(totalnew + ‘ copies of the case have been successfully created giving ‘ + grandtotal + ‘ total occurencies.’)
    oSource.SaveAndClose();
    window.close();
    }

    </script>

  17. chanpreet says:

    I would like to use this code in a slightly different. i would like to provide a create link on the account page which launches the case screen and populates few fields in the case screen from the source screen (Like ph or something)

    i can do that using clonecase.htm as the base.

    I was thinking of providing the create link to this htm page. In the htm page launch /cs/cases/edit.aspx and then map fields from the account page to the cases page. I get script errors "document – object could not be found" if i introduce any mappings

  18. Steve says:

    chanpreet – I may be wrong on this but I think you’d find this easier if you simply set up some relationships between the account and case entities for the fields you want to carry across.

    Then, create cases from the account by selecting the "actions" drop down menu in the account followed by "add related -> case".

    The new case will be linked to the open account and the fields you created relationships for should copy over without any jscript coding required.

    Hope this helps.

  19. John says:

    I’ve tried the code and it works great EXCEPT for that I can’t seem to copy the date field. Anyone know how to get it to work. Even though the date is filled in it complains that it’s either null or doesn’t exist.

  20. Steve says:

    Try copying it into a variable then across to the new form.

    I’ve managed to set dates by copying the original value to a variable, adding a number of days onto the variable then assigning the new date value to the new copy of the case.

    I imagine the same code should work without adding on any days, if not, just add 0 days on to keep it the same date.

    Code example:

    var mondate = window.dialogArguments.document.crmForm.all.new_startdate.DataValue;

    mondate.setDate(mondate.getDate()+7);

    oClonedCase.document.crmForm.all.new_mondate.DataValue = mondate;

    That worked ok for me, we did also have problems copying dates directly – i think you need to set it to a variable of type ‘date’ as above then it goes in ok.

    Hope that makes some sort of sense.

  21. Brett says:

    I am trying to copy a sales order for a CRM 1.2 installation.  I have used the clonecontact from the 8525a Customizations CD and redirected to the Sales Order.  However, when I run the code it errors with

    ‘document’ is null or not an object.

    Any help would be appreciated!

    Thanks,

    Brett

  22. Brett says:

    Here is the code for the above post:

    <html>

    <title>Clone Order</title>

    <style>

    BODY, TD

    {

    font-family: arial;

    font-size: 12px;

    }

    TD.body

    {

    border-bottom:  solid 1px #cccccc;

    text-align: center;

    }

    </style>

    <script language="javascript">

    // Set global variable for the cloned order window

    var oClonedOrder;

    function window.onload()

    {

    // Open a new Order form

    oClonedOrder = window.open(‘/sfa/salesorder/edit.aspx’,”,’menubar=0, status=1, width=1000, height=600′);

    // Set a timeout to wait for the new contact form to load

    setTimeout(‘checkPageState()’,100);

    }

    // Checks if the new order form has completed loading

    // When it completes, CloneOrder will be called

    // If it’s not loaded, it will set a timeout and check again.

    function checkPageState()

    {

    if (oClonedOrder.document.readyState == ‘complete’)

    {

    CloneOrder();

    return;

    }

    setTimeout(‘checkPageState()’,100);

    }

    function CloneOrder()

    {

    // Get a pointer to the parent window

    var oParent = window.dialogArguments;

    var oSource = oParent.document.crmForm;

    // With the target crmForm

    with(oClonedOrder.document.crmForm)

    {

    // General fields

    customerid.DataValue = oSource.customerid.DataValue;

    pricelevelid.DataValue = oSource.pricelevelid.DataValue;

    totallineitemamount.DataValue = oSource.totallineitemamount.DataValue;

    discountpercentage.DataValue = oSource.discountpercentage.DataValue;

    discountamount.DataValue = oSource.discountamount.DataValue;

    totalamountlessfreight.DataValue = oSource.totalamountlessfreight.DataValue;

    freightamount.DataValue = oSource.freightamount.DataValue;

    totaltax.DataValue = oSource.totaltax.DataValue;

    totalamount.DataValue = oSource.totalamount.DataValue;

    }

    // Finally, close the dialog

    window.close();

    }

    </script>

    <body>

    <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0" align ID="Table1">

    <tr valign="middle">

    <td class="body" align="center">

    <div style="font-size= 10pt; font-family= Tahoma;">Duplicating Order…</div>

    </td>

    </tr>

    </table>

    </body>

    </html>

  23. Steve says:

    I getting an error in the Outlook Client on the pointer to the parent window.  Would you happen to know how to solve this issue?

  24. miiki says:

    When I click Clone button, I am able to open a new form but the values are not loaded on the cloned new form.why this happens?Please help me i am blocked at this point and i am in need to implement this clone functionality.

  25. Mohsen says:

    If there is a radio Button in master form how can I customize the Javascript code for copying its value to target form?

  26. Branko says:

    How do I insert the clone button into a case form. I dont se it right now.

  27. Eli says:

    I have several custom entitites under a case.   They are used to store multiple entries as they relate to a specific case type.  I would like to clone them when I clone a case.  Any ideas?

  28. Branko says:

    About the button… solved… sorry…

  29. Hollie Cox says:

    I’ve used your example to create copies of custom objects and it’s worked great.  What about cloning quotes?  How can I handle cloning both the header and detail information?

  30. Ben Vollmer says:

    Holly… I had a developer write me a little piece of code to do that and put it on the ISV.CONFIG bar. Because Quotes are TWO seperate entities, using this isn’t possible. :-)

    Sorry about that!

    Ben

  31. james says:

    There is a pre-existing "clone contact" button on the crm vpc, I tried making changes to the code which is located in …crmwebclonecontactclonecontact.htm, but none of the changes show up on the crm.  I’ve tried simply reopening the crm and an iis reset, both haven’t worked.  Any suggestions?

  32. Ben Vollmer says:

    James,

    Did you utilize the ISV.config to add the button to CRM?

    HTH

    Ben

  33. james says:

    yes, the button is on crm.  it’s actually pre-existing code on the crm vpc that i didn’t know was on here until i poked around.

  34. ben says:

    I’m attempting to clone opportunities, when I clone the form nothing comes through.  I’ve commented all the fields I want to pass through except for the code below just to see if it’ll pass through, but it hasn’t.

    name.DataValue = oSource.name.DataValue;

  35. James,

    Did you delete the temporary Internet files in IE? The HTM is cached and when you change it, you will need to delete it from cache.

    Stefan

  36. My apologies in not getting this up sooner. I flew home on the red-eye on Wednesday night, drove from

  37. Richard says:

    This is an extremely useful posting. I have a question concerning the closing of an opportunity. I have created a new statuscode of 6 to indicate “Lost-Modified “. When I try to change the status from the .htm code using oSource.statuscode.DataValue = 6, It does not seem to work.

    Any insights would be welcome.

    Thank you,

  38. Ben Vollmer says:

    Richard,

    Have you tried SelectedText = Lost Modified? I have not played with it, but look in the Picklist area of the CRM SDK for some examples..

    Thanks!

    Ben

  39. Richard says:

    Yeah I have and was able to directly manipulate the attributes for the status code and state. But when I save the opportunity these changes do not hold. I have been poking around the SDK and have found out that there is the opportunityclose Class and that i have to invoke it to actually make the changes to the opportunity in question.

    My question is how to place this into the code that you have posted here. I have tried diferent manners but all of the samples from the SDK do not resemble the structure you have here.

    Thank you for your help!!

  40. Christian E. says:

    Great simple script!  I’ve adapted it to create a follow-up phone call button that includes the phone number (which was a big complaint from the sales guys after using native CRM follow-up functionality).

    One quick question though.  I haven’t been able to auto-populate the "Recipient" field because I get a "Duplicate Record" error message upon saving.  Commenting that line out allows me to save it successfully, but then the "Recipient" field is blanked out.  Any ideas?  Much appreciated…

  41. Andrew says:

    Works great.

    We would like to clone all the case information including the followupby field and our license expire field.

    But how can I clone data fields as well without receiving the undefined error?

  42. It works for me in my web client, but I receive an error message when I try to launch the Clone a Case button in Outlook.  The error message pops up in a very small fixed box that I cannot expand to get the details.  Any ideas?  Anyone?

  43. Tony Pascone says:

    Great info! Played arund a bit and got things worning with Contacts and Cases and am also trying to do the same ting for a custom entity. However, there is no edit.aspx for cutom entities?? Or is there??

  44. Jim Daly says:

    Tony –

    Custom entities use a generic edit.aspx  It includes a querystring something like "..edit.aspx?etc=1001"

    ETC is Entity Type Code. Each custom entiity has it own ETC.

    To see the full URL if you are running in application mode –  open an existing custom entity record and press Ctrl+N. This will expose the address bar in the new window.

  45. Steve Bauserman says:

    I am atempting to clone service appointments. All I need it the basic information in the top part of the screen which works fine.  After I select a new date and click on "Save" or "Save and Close", I receive an error that an event of the same name exists.  I have tried to change the subject, but receive the same error.  Any suggestions.

  46. Andrei P. says:

    Christian E.,

    I’ve also adapted this sample to create a follow-up phone call.

    May be this piece of code will be useful for you…

    function ClonePhone()

    {

    // Get a pointer to the parent window

    var oParent = window.dialogArguments;

    var oSource = oParent.document.crmForm;

    var to_lookupItem = new Array;

    // With the target crmForm

    with(oClonedPhone.document.crmForm)

    {

    // Overview fields (here onle Recipient" field )

    to_lookupItem = oSource.all.to.DataValue;

    var lookupData = new Array();

    var lookupItem= new Object();

    //Set the id, typename, and name properties to the object.

    lookupItem.id = to_lookupItem[0].id;

    lookupItem.typename = to_lookupItem[0].typename;

    lookupItem.name = to_lookupItem[0].name;

    lookupItem.type = to_lookupItem[0].type;

    // Add the object to the array.

    lookupData[0] = lookupItem;

    all.to.DataValue = lookupData;

    }

    // Finally, close the dialog

    window.close();

    }

  47. Aad says:

    Hi Ben,

    This is so frustrating, everybody seems to get it right but I keep getting this error: "oSource.ticketnumber.DataValue is null or not an object" I would really appreciate if you could help me out here! Aad.van.der.velden@gmail.com

  48. Ben Vollmer says:

    Just remark that field out… It is very simple to do… It should take about 30 seconds.

  49. Aad says:

    Hi Ben,

    Thanks for your reply. Even if I fysically remove the line causing the error it still produces the same error.. how weird is this? And I tried it both in the May VPC and my own VPC..

  50. Ben Vollmer says:

    Did you clean out your IE Cache?

  51. raybeste says:

    There have been several posts above about this not working in the Outlook client.  Is there a known change to this code that will allow this to work properly in the Outlook client?

  52. raybeste says:

    For those that have discovered that this code or any code similar that is called from the outlook laptop client will fail, the reason is linked to the fact that the outlook laptop client does not use IE (it uses Cassini) and as such, there doesn’t seem to be a way to allow Cassini to allow cross domain references.  So, the dialogArguments reference fails in the code so you can not get a pointer back to the calling form to get the values.  A solution would be to copy this clone.htm file to each user’s local crm folder and call it directly with the localhost:2525 – this works but is a pain for deployment – the other solution would be to re-write this using server side calls to the crm web service but the user experience would not be as clean I don’t think

  53. Ben Vollmer says:

    I want to play with this under 4.0… The outlook client in 4.0 for desktops will use the IIS Pages… So this may work… Let me play with it.

  54. Aad says:

    Hi Ben,

    I got the cloning to work but it will not update the master case in the parent record… no error message, just nothing happening.. any thought would be welcome!

    Aad

  55. Wolfgang Jansen says:

    we had also trouble with copying dates and bit fields from the master to the cloned order.

    Replacing:

    willcall.DataValue = oSource.willcall.DataValue;

    With:

    var willcallbit = window.dialogArguments.document.crmForm.all.willcall.DataValue;

    oClonedOrder.document.crmForm.all.willcall.DataValue = willcallbit;

    seems to solve it.

    But why??

  56. Rev says:

    Hi,

    When I migrated the clone phonecall frm crm 3 to crm 4, notices that it only works if the user has administrator privilege. The user is unable to view the clone icon on the toolbar without this privilege. It was never this case when I implented it in CRM 3.0 based on your post.

    Please advise on how I can get it working for all the user without granting them the system administrator/system customizer role.

  57. mscrm-newbie says:

    Hi,

    I m trying to implement the above features in MSCRM 4 environment for entity phonecall.

    Tried to modify the ISV.Config file. I tried the below codes but it didn’t allow me to import the customization into the system. Appreciate if someone can tell me where I went wrong.

    =============Codes=======================

    <Entity name="phonecall">

    <ToolBar ValidForCreate="0" ValidForUpdate="1">

    <Button Icon="/_imgs/ico_16_137.gif" Url="/ClonePhonecall/ClonePhonecall.htm" WinParams="dialogHeight:100px;dialogWidth:300px;" WinMode="1">

                     <Titles>

                       <Title LCID="1033" Text="Follow-up Phonecall" />

                     </Titles>

                     <ToolTips>

                       <ToolTip LCID="1033" Text="Create a Follow-up of This Call" />

                     </ToolTips>

                   </Button>

    </ToolBar>

  58. mscrm-newbie says:

    Hi,

    Manage to solve the problem yesterday. This is the piece of code that works for the ISV in my case.

    =================codes========================

    <Entity name="phonecall">

             <!– The Phonecall Tool Bar –>

             <ToolBar ValidForCreate="0" ValidForUpdate="1">

               <Button Icon="/_imgs/ico_16_137.gif" Url="/ClonePhonecall/ClonePhonecall.htm" PassParams="1" WinParams="" WinMode="0">

                 <Titles>

                   <Title LCID="1033" Text="Follow-up " />

                 </Titles>

                 <ToolTips>

                   <ToolTip LCID="1033" Text="Create a follow-up phonecall" />

                 </ToolTips>

               </Button>

               <ToolBarSpacer />

             </ToolBar>

        </Entity>

    =====================End=======================

    Now I can’t seem to copy the details from the master form to the copy. Is there any changes to the code for MSCRM 4?

    Hope someone can shed some light on this matter.

    Thanks in advance

  59. Dating says:

    So recently on one of our internal discussion aliases, somebody asked about how to have a master case with a number of “sub-cases.” This is handy when you have a number of issues like a service outage or patch that doesn’t quite apply as desired. J S

  60. Weddings says:

    So recently on one of our internal discussion aliases, somebody asked about how to have a master case with a number of “sub-cases.” This is handy when you have a number of issues like a service outage or patch that doesn’t quite apply as desired. J S

  61. Al says:

    If you want to save yourself some time c360 produce a FREE record cloning utility http://www.c360.com/Clone.aspx

    I have tested it and it works very well, including allowing you to exclude fields from the cloning process.

  62. What is the basic purpose, i mean application of cloning a case in REAL TIME….. I am expecting fast response from any one…

  63. There are several nice examples that show how to clone a record in MS CRM. Most of the examples I found cloned native entities: Cases, Contacts, Opportunities, etc. I needed to clone a c …

  64. jphuebner says:

    Has anyone solved the quote detail cloning question? I have a similar requirement (for salesorders), and understand that it requires a server-side approach. Has anyone resolved this?