Nov 9, 2011

Custom recalculation button for opportunity

Scenario: It is required to calculate the cost in opportunity. Usually, opportunity consists of Recalculation button to calculate few values, but not cost as I need. First I tried to find a way to fire my own JavaScript to do that with the same button, but I learned it is not a recommended attempt. So now I am trying to implement my own Button to do all the calculations (my way) and hide the existing calculation buttons.

To add/ Hide buttons I need to modify the ribbon. In order to modify the ribbon it is needed to import the customization of particular entity. For clarity I will mention below steps;

Create solution and add only the entity we need to modify the ribbon.
  1. Export it (Don’t add any other depending objects/ export as unmanaged solution)
  2. Unzip the file (it will give three XML files)
  3. Modify the customizations.xml file accordingly (which we will discuss)
  4. Zip the files again
  5. Import the file and publish
To play around with Ribbon, there are some resources to be referred. SDK has provided a XML file for each entity in sdk\resources\exportedribbonxml folder. For my example with opportunity, I can open opportunityribbon.xml. So practically, we need to open two XML files when we need to modify a ribbon.

  1. Costomization.xml (TO MODIFY)
  2. <entityname>ribbon.xml (TO REFER)
Reference file contains all the information about existing buttons, locations and their characteristics such as abilities and visibility. First we will hide the existing Recalculate buttons. When I simply search the reference file I found two button Ids for this (Mscrm.Form.opportunity.Recalculate, Mscrm.HomepageGrid.opportunity.Recalculate).

Buttons can be placed in three main ways in ribbon.

Mscrm.Form.<entityname> – button appears when form is opened for selected record.
Mscrm.HomepageGrid.<entityname> – button appears when grid is shown (multiple records)
Mscrm.SubGrid.<entityname> - Button appears when records appear within a subgid of some other entity

Now adding below entries within the <CustomActions> tag will do the hiding of both Recalculate buttons.

<HideCustomAction Location="Mscrm.Form.opportunity.Recalculate" 
   HideActionId="Mscrm.Form.opportunity.Recalculate.HideAction" />
<HideCustomAction Location="Mscrm.HomepageGrid.opportunity.Recalculate" 
   HideActionId="Mscrm.HomepageGrid.opportunity.Recalculate.HideAction" />

Now I am trying to add my own button with instructions to fire my javascript method. Add below entry within <CustomActions> and <CommandDefinitions> tags respectively.

<CustomAction Id="CA_CUSTOM_Recalculation" Location="Mscrm.Form.opportunity.MainTab.Actions.Controls._children" Sequence="8">
  <CommandUIDefinition>
    <Button Id="B_CUSTOM_Recalculation" 
            Command="Cmd_CUSTOM_Recalculation" 
            LabelText="Recalculate Job" 
            ToolTipTitle="Recalculate Totals, Costs and Margin" 
            ToolTipDescription="This recalculates Job Price, Job Cost and Job Margin" 
            TemplateAlias="o1" 
            Image16by16="/_imgs/SFA/Recalculate_16.png" 
            Image32by32="/_imgs/ribbon/recalculateopportunity32.png"/>
  </CommandUIDefinition>
</CustomAction>

<CommandDefinition Id="Cmd_CUSTOM_Recalculation">
  <EnableRules>
    <EnableRule Id="Mscrm.CanWritePrimary" />
    <EnableRule Id="Mscrm.OpportunityIsOpen" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteOpportunity" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction Library="$webresource:new_recalculations.js" 
                        FunctionName="JobCalculationSinglejob">
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>



Here CustomAction Id and Button Id are a two unique values I gave to my Custom Action and Button respectively. If you look carefully, it’s noticeable that I have given a command name and use that when I define the command later on. Though location value is bit tricky, I have checked the reference file and found the location of the existing recalculate buttons for that. “_children” postfix is to tell that button should come under that. Sequence number is a number to arrange the buttons with the existing buttons. Other buttons in same location were having numbers 5, 6 and 7 and I wanted to add my one at the end, which I put 8.

Command definition is used to define the behaviour of my button and it’s obvious to see how it calls a method within the JavaScript which has been saved as a webresource. Also I have done a cunning work here. Since I am going to perform a calculation, I copied (from reference file) the enablerules and displayrules from the rules of existing recalculation button. So my button will behave the same way.

Now I am free to do calculation within my Javascript method with my own rules!

2 comments:

  1. thx for this tip. I need to know how you work with selected opportunity from the grid. How can you read and write data with javascript in an opportunity without open it ?

    ReplyDelete
    Replies
    1. Hi Birenens,

      According to my example JobCalculationSinglejob(ID) function get fired on click and it get ID which is Guid of selected record.

      We can use CRM service in JS. I prefer to use a library called Ascentium CrmService, that gives you easy way of doing all the operations like create, update & etc. This page explaines sample codes. http://www.avanadeblog.com/xrm/2010/05/a-microsoft-dynamics-crm-javascript-sdk-in-celebration-of-an-amazing-year-.html

      Please send me an email (sumedha7@gmail.com), so that I can send you the library file you need to use.

      Delete