Jun 30, 2011

Filtered lookup

This is simple trick that could improve the usability of a CRM application. Let me explain the requirement first. For example, we might need to add a potential customer to an entity main form. Also we might need to add a contact to the same form. In this case, most practical requirement is to show the contacts relevant to the selected customer.

Please use this function in onload of the form.

FilterLookupUponParent = function(source, target)
{
if (IsNull(source) || IsNull(target)) { return; }
var name = IsNull(source.DataValue) ? '' : source.DataValue[0].name;
target.additionalparams = 'search=' + name;
}

Use this code to call the function, passing the form field names.

FilterLookupUponParent(crmForm.all.new_accountid, crmForm.all.new_primarycontactid);

Here it is illustrated that, RAW Ltd has two contacts.


Once we use above code, when clicking the lookup field will pop up the lookup window only with those contacts that are relevant to the selected RAW Ltd. This is actually a filter. Once you release the filter, you get all the contacts.


Actually, it is also wise to call the same method is onChange event of the customer, because filter should get changed accordingly.

Hope this will help you.

Jun 23, 2011

Enhancing the Lead conversion functionality

Converting a lead to an Account/Contact/Opportunity is a standard function provided by Dynamic CRM. Either you disqualify the lead or qualify (convert). Modifying the provided convert page is quite restricted. Below article shows how to hide some of the covert options.

If you want to covert the lead to some other entity, for example, to a custom entity, it’s impossible with standard convert page. When I came across this requirement, I implemented a solution without the standard page.

This solution was flexible, but contained few steps.

1) Hide the button to the standard lead convert page.
2) Add my own menu system to lead entity
3) Implement disqualify method
4) Implement qualify(convert) method

Will consider the steps in detail;

1) Hide the button to the standard lead convert page.

I could call below method to hide the lead convert button.

hideStandardQualifyingButton = function() 
{
var lis = document.getElementsByTagName('LI');
var i = 0;
while (i < lis.length) 
{
    if (lis[i].getAttribute('title') == 'Qualify or disqualify the lead') 
    {
      //lis[i].outerHTML = '<SPAN></SPAN>' this gives errors for resizing the window afterwords
      lis[i].outerHTML = '<SPAN> <SPAN> <SPAN> <SPAN> </SPAN> </SPAN> </SPAN> </SPAN>'; 
    }
    i = i + 1;
}
}


If you check the web, you will see few places that suggest this code with the line I have commented. That works fine, but throws a page error when user resizes the browser window. Then the next line was introduced, instead.

2) Add my own menu system to lead entity



If you have play around with ISV file, this won’t be a hard task. Below are the new entries in lead entity for this.

<CustomMenus>
              <Menu>
                <Titles>
                  <Title LCID="1033" Text="Lead Conversion" />
                </Titles>
                <MenuItem JavaScript="LeadQualify();">
                  <Titles>
                    <Title LCID="1033" Text="Lead Convert" />
                  </Titles>
                </MenuItem>
                <SubMenu>
                  <Titles>
                    <Title LCID="1033" Text="Disqualify" />
                  </Titles>
                  <MenuItem JavaScript="LeadDisQualify(4);">
                    <Titles>
                      <Title LCID="1033" Text="Already Known" />
                    </Titles>
                  </MenuItem>
                  <MenuItem JavaScript="LeadDisQualify(6);">
                    <Titles>
                      <Title LCID="1033" Text="No Longer Interested" />
                    </Titles>
                  </MenuItem>
                </SubMenu>
              </Menu>
            </CustomMenus>


3) Implement disqualify method

This is the simple code you can use to disqualify the lead. ReasonCode is the integer value of disqualification reason.

oService.SetState("lead", _leadid, "Disqualified", ReasonCode);


If you want to further extend the disqualifying reasons, it’s possible. You can simply add whatever the new entries in entity in the standard way as below.

Now you can pass the relevant values to the same method. (Of course you need to add/edit the menu items in step 2 accordingly)

4) Implement qualify(convert) method

This is where you get the real fruit of the exercise. Now you can programmatically do your steps to convert your lead to any entity, including your own custom entities. For example this is a simple code I used to convert the lead to a custom entity called regional project (new_regionalproject).

var _leadid = crmForm.ObjectId;
    var _bEntity = new BusinessEntity("new_regionalproject");
    _bEntity.attributes["originatingleadid"] = _leadid;
    _bEntity.attributes["firstname"] = _firstName;
    _bEntity.attributes["lastname"] = _lastName;
    ....
    ....
 return _oService.Create(_bEntity);

Now we need to change state of the lead to qualified.

oService.SetState("lead", _leadid, "Qualified", 3);


Notes:

1) In step 4, you can actually implement any business logic since you are free to write the code before qualifying the lead. You can even Update or Associate with other entities accordingly.
For example I have converted the lead to account and created a Quote (without Quote products) using particular account as the potential customer.

2) In qualifying/disqualifying, you got to use the given methods. (i.e. SetState) Don’t try to call Update method here Since its not allowed.

Hope this will help you.