Convert to Opportunity - Add a message from webpage

When you attempt to convert a lead that is not matched to a company, the system displays a message as follows...

Is it possible to add an additional message? We want to add a message to alert the user that they cannot convert the lead to an opportunity until they have populated either the phone OR email field (they don't have to populate) both.

I know how to hide the button based on field values. However, that is not what the client is looking for. They want a message to display.

Is it possible to add a message? If so, I would greatly appreciate someone pushing me in the right direction in regards to where I could go to add this.

Thanks!

  • 0

    So this is a simple looking complex requirement by your customer.

    Would they prefer to convert the lead to opportunity from lead workflow, you can create an action in the workflow to convert to opportunity and remove that button.

    This way you will have more control over client side validation.

  • 0

    This is how I would do it.

    To play along, put this code into the custom content.

    $(document).ready(function () {
    replaceClickHandler("Button_ConverttoOpportunity", "convertToOpp");

    });

    function convertToOpp(orig) {

    //perform the original validation to test if the Company is matched:
    var companyValidated = SageCRM.wsLead.ValidateCompanyEntry(-1);

    //test if either email or phone has a value
    var emailOrPhoneValidated = (crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());
    if (companyValidated && emailOrPhoneValidated) {

    //if both validations passed, invoke the original
    //button function:
    var fnStr = orig.substring(11);
    var convertFn = new Function(fnStr);
    convertFn();
    }else{
    //if the validations
    if(!emailOrPhoneValidated) { alert('You must enter either a phone number or an email address.'); }
    }
    }

    function replaceClickHandler(btnName, saveName) {
    var existingFunction = $("#" + btnName + "").attr("href");
    $("a[id='" + btnName + "']").attr("href", 'javascript:' + saveName + '("' + existingFunction + '")');
    }

    So, what we are doing is : in document.ready we're getting hold of the convert button and telling it to run our own 'click' method called 'convertToOpp'. The cunning bit is that we pass in the button's original href as an argument into our new click method. In 'convertToOpp' we call the built-in code that does the matched-company validation, then our own check on the email/phone. If both validations pass then we convert the 'original' href string back into a function and invoke it. If not then we get the original validation message courtesy of the call the SageCRM.wsLead.ValidateCompanyEntry and our own message if the email/phone validation fails.

    (oh, and before anyone puts their Douglas Crockford hat on to tell me how terrible it is to be creating a function from a string, I know and I don't care).

  • 0

    Hi Sharad: Thank you for the reply!

    If we convert the lead to an opportunity from the lead workflow, do we lose the “View Lead” button on the Opportunity for the converted Lead? Also, same on the converted lead, do we lose the “View Opportunity” button. If so, I don’t think that will be acceptable to the client.

    I am going to see if it will be acceptable for me to "Hide" the convert to Opportunity button until the required fields are populated.

    I think I have mostly worked out the "if" statement that would be required as they want EITHER the email or phone to be required but not BOTH..along with some other more straight forward fields.

    If hiding the button until the fields are populated is not acceptable, I was thinking about trying to add some code to the custom content box. I am not sure exactly how I would write the code...but I was thinking if I could get a hold of the button (with getelementbyid ?) that "on-click", I would add a message block based on my if statement. I am not sure if what I am thinking is possible, this is just my "theory". I am not a "real" programmer, I just play one in Sage CRM. :-)

    Thank you for any assistance you can provide.

    Any assistance is greatly appreciated! :-)

  • 0

    Chris: Thank you so much! I appreciate how well you explain things! I will give this a try and see how it works for me.

    Again...Thank you! Thank you!

  • 0

    Chris: Hmmm. I must be doing something wrong. If I put the code in exactly as written, it is not working. Therefore, I am guessing I was supposed to make some modifications to the example before I pasted it. I put the code in the custom content box of the LeadCustomScreen as displayed below.

    The company and person record are already matched and when I click the Covert to Opportunity button, the system proceeds to convert the lead to an opportunity even though neither the lead_personphonenumber or the lead_personemail have a value in them.

    I am going to see what the system returns for var emailOrPhoneValidate as a place to start..but if you know where I need to look, I would greatly appreciate a shove in the right direction.

    Thank you!!

    $(document).ready(function () {

    replaceClickHandler("Button_ConverttoOpportunity", "convertToOpp");

    });

    function convertToOpp(orig) {

    //perform the original validation to test if the Company is matched:

    var companyValidated = SageCRM.wsLead.ValidateCompanyEntry(-1);

    //test if either email or phone has a value

    var emailOrPhoneValidated = (crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());

    if (companyValidated && emailOrPhoneValidated) {

    //if both validations passed, invoke the original

    //button function:

    var fnStr = orig.substring(11);

    var convertFn = new Function(fnStr);

    convertFn();

    }else{

    //if the validations

    if(!emailOrPhoneValidated) { alert('You must enter either a phone number or an email address.'); }

    }

    }

    function replaceClickHandler(btnName, saveName) {

    var existingFunction = $("#" + btnName + "").attr("href");

    $("a[id='" + btnName + "']").attr("href", 'javascript:' + saveName + '("' + existingFunction + '")');

    }

  • 0

    Well - first off I'd not put the stuff into CustomContent directly. Not that it makes any differnce at runtime, but if you put the code in an external file and just point the CustomContent to it, then it'll be far easier to debug in your dev tools of choice (let's face it : that means the Chrome developer tools).

    But, were we going to do this in situ, as it were, I'd first test that the 'replaceClickHandler' function was doing its job by simply changing the convertToOpp function to be:

    function convertToOpp(orig){

    alert('this seems to be working');

    }

    If that works - in that all that happens when you click the convert button is you get the alert, then expand it to:

    function convertToOpp(orig){

    var emailOrPhoneValidated = (crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());

    alert(emailOrPhoneValidated); /* if both fields are empty this'll just be an empty string */

    alert(!!emailOrPhoneValidated); /* this converts the inherent 'truth-iness' of a string to its boolean representation - which should be 'false' if it's blank. */

    }

    See where you get with that.

  • 0

    Well.....yeah : the message text in the original alert comes from the translation of Capt_Code 'NoPersonSelectedConvertLeadtoOpp', but changing it wouldn't really help for this use case - as we still need to do that secondary bit of validation to test whether either of the phone or email fields have values and if not (a) inform the user and (b) prevent the conversion.

  • 0

    I'd have assumed this was just a translation in the system that you could change

  • 0

    Chris: I was able to get this to work but consistently. I wonder if the system is caching and causing me an issue.

    As I ran through the code with the alerts, I was able to get the correct result.. with blank or false.

    Therefore, I changed the code back to the original (which means the alerts would display if the Convert to Opportunity button was clicked and the validation failed.)

    However, I was surprised to see the testing alerts displayed whenever I opened a lead that was previously tested.

    I tried rebooting the system...but it was still there. Then I was looking over the code and doing some research and I went back and tried it again and the testing alerts did not show. Therefore, I followed through on testing the Convert to Opportunity button and it worked for my two examples...one with a phone or email and one without. Yeah!

    The client also wanted some more simplistic validation (or so I thought :-) ) so I tried to expand on your code to add the Address, City, State and Zip in. I added an email address to both my test leads so that the address information was the only information missing on one of the leads. The first lead continued on to the convert as expected as all the data was there. However, the second lead also continued on. It seemed to run the original code before I added the address info in. It verified that there was an email address and let it go through. Therefore, I am not sure where I went wrong. It seems like my logic was good on how to modify it ... but not good enough because it does not work.

    Am I on the right track? Can you shove me in the right direction? I greatly appreciate your assistance!

    crm.ready(function () {

    replaceClickHandler("Button_ConverttoOpportunity", "convertToOpp");

    });

    function convertToOpp(orig) {

    //perform the original validation to test if the Company is matched:

    var companyValidated = SageCRM.wsLead.ValidateCompanyEntry(-1);

    //test for company name (Won't pass the original validation if the company name is empty);

    //test for first and last name (You cannot create a lead without the first name and last name);

    //test for company address

    var address1Validated = (crm.fields('lead_companyaddress1').val() );

    var cityValidated = (crm.fields('lead_companycity').val() );

    var stateValidated = (crm.fields('lead_companystate').val() );

    var zipValidated = (crm.fields('lead_companypostalcode').val());

    //test if either email or phone has a value

    var emailOrPhoneValidated = (crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());

    if (companyValidated && address1Validated && cityValidated && stateValidated && zipValidated && emailOrPhoneValidated) {

    //if both validations passed, invoke the original

    //button function:

    var fnStr = orig.substring(11);

    var convertFn = new Function(fnStr);

    convertFn();

    }else if{

    //if the validations

    if (!address1Validated) { alert ('You must enter Address 1.');}

    }else if{

    if (!cityValidated) { alert ('You must an Address City.');}

    }else if{

    if (!stateValidated) { alert ('You must an Address State.');}

    }else if{

    if (!zipValidated) { alert ('You must enter an Address Zip.');}

    }else{

    //the phone and email is an either, or. You must have one but don't need both.

    if(!emailOrPhoneValidated) { alert('You must enter either a phone number or an email address.'); }

    }

    }

    function replaceClickHandler(btnName, saveName) {

    var existingFunction = $("#" + btnName + "").attr("href");

    $("a[id='" + btnName + "']").attr("href", 'javascript:' + saveName + '("' + existingFunction + '")');

    }

    P.S. I did move the code to a script file and am referencing it from the custom content box. That was the first thing I did and I did all the testing through the .js file. :-)

    Again...Thank you!!!

  • 0

    OK...so I am just an idiot in regards to the code. I realized while I was working on something else, that I did my else if statements wrong. Therefore, I fixed them and I am now 98% there. They all work except the zip code. (YEAH!) Even if the field is populated, I get a message that it is not. Do I need to do something different in regards to that field? I cannot see what I am doing wrong. Any assistance is greatly appreciated!!

    crm.ready(function () {

    replaceClickHandler("Button_ConverttoOpportunity", "convertToOpp");

    });

    function convertToOpp(orig) {

    //perform the original validation to test if the Company is matched:

    var companyValidated = SageCRM.wsLead.ValidateCompanyEntry(-1);

    //test for company address

    var address1Validated = (crm.fields('lead_companyaddress1').val() );

    var cityValidated = (crm.fields('lead_companycity').val() );

    var stateValidated = (crm.fields('lead_companystate').val() );

    var zipValidated = (crm.fields('lead_companypostcode').val());

    //test if either email or phone has a value

    var emailOrPhoneValidated = (crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());

    if (companyValidated && address1Validated && cityValidated && stateValidated && zipValidated && emailOrPhoneValidated)

    {

    //if both validations passed, invoke the original

    //button function:

    var fnStr = orig.substring(11);

    var convertFn = new Function(fnStr);

    convertFn();

    //if the validations

    }

    else if (!address1Validated)

    {

    alert ('You must enter Address 1.');

    }

    else if(!cityValidated)

    {

    alert ('You must an Address City.');

    }

    else if (!stateValidated)

    {

    alert ('You must an Address State.');

    }

    else if (!zipValidated)

    {

    alert ('You must enter an Address Zip.');

    }

    else

    {

    //the phone and email is an either, or. You must have one but don't need both.

    if(!emailOrPhoneValidated) { alert('You must enter either a phone number or an email address.'); }

    }

    }

    function replaceClickHandler(btnName, saveName) {

    var existingFunction = $("#" + btnName + "").attr("href");

    $("a[id='" + btnName + "']").attr("href", 'javascript:' + saveName + '("' + existingFunction + '")');

    }

    Again---Thank you! Thank you!! Thank you!!!

  • 0

    Not sure why one field wouldn't validate like that. That said, here's a slightly more tidied-up version. In the case of the address fields we'll use a Regex to make sure it's not just a blank string that's giving a false positive:

    $(document).ready(function () {

    replaceClickHandler("Button_ConverttoOpportunity", "convertToOpp");

    });

    function convertToOpp(orig) {

    //perform the original validation to test if the Company is matched. If not, we'll bail out straight away
    if (SageCRM.wsLead.ValidateCompanyEntry(-1)) {

    var addressValidated = false;
    var msg = '';

    //test if either email or phone has a value (this is a special 'or' case)
    var emailOrPhoneValidated = !!(crm.fields('lead_personphonenumber').val()
    || crm.fields('lead_personemail').val());

    if (emailOrPhoneValidated) {
    var addressFields = [

    {
    fieldName: 'companyaddress1',
    message: 'a value in Address 1'
    },
    {
    fieldName: 'companycity',
    message: 'an Address City'
    },
    {
    fieldName: 'companystate',
    message: 'an Address State'
    },
    {
    fieldName: 'companypostcode',
    message: 'an Address Zip'
    }
    ]

    for (i = 0; i

    addressValidated = !!(crm.fields('lead_' + addressFields[i].fieldName).val().replace(/\s/g,'').length);
    msg = addressFields[i].message;
    if (!addressValidated) break;
    }

    }
    if (emailOrPhoneValidated && addressValidated) {
    var fnStr = orig.substring(11);
    var convertFn = new Function(fnStr);
    convertFn();

    } else {

    if (!emailOrPhoneValidated) { alert('You must enter either a phone number or an email address.'); return; }

    if (!addressValidated) { alert('You must enter ' + msg + '.'); return; }
    }
    }
    }

    function replaceClickHandler(btnName, saveName) {
    var existingFunction = $("#" + btnName + "").attr("href");
    $("a[id='" + btnName + "']").attr("href", 'javascript:' + saveName + '("' + existingFunction + '")');
    }

  • 0

    Plugged this code into a JS file, tried clicking the lead screen convert to opportunity button with email and address data entered, this still calls the standard function via the translation. Not sure if am missing anything here

  • 0

    Have you debugged through the JS code to see what it's doing? Right at the top of convertToOpp() we call do this:

    if (SageCRM.wsLead.ValidateCompanyEntry(-1)) {

    ... }

    That's the call to the built-in standard validation. If that returns false (i.e. the company/person isn't matched) then you'll get the standard message box (which is invoked by the ValidateCompanyEntry() function itself) - and the custom validation doesn't run as there's no point in going any further.

  • 0

    the replaceClickHandler is resulting as undefined, the return to the function SageCRM.wsLead.ValidateCompanyEntry(-1) is "true"

  • 0

    ok i moved ahead a bit with the debug and found that the following variable was not getting the result

    var emailOrPhoneValidated = !!(crm.fields('lead_personphonenumber').val()

    || crm.fields('lead_personemail').val());

    i had the email filled but the phone number was empty, this sets the result of emailOrPhoneValidated as Uncaught SyntaxError: Invalid or unexpected token

    however when i try the below with in the chrome developer console

    var emailOrPhoneValidated = !!("" || "[email protected]");

    this results in undefined, and shows the new convertToOpp function alert ("You must enter a Value in Address 1") so not sure if there is a clean up required in the statement

    var emailOrPhoneValidated = !!(crm.fields('lead_personphonenumber').val() || crm.fields('lead_personemail').val());

  • 0

    If you run something like...

    var xxx = !!('' || '');

    ...in the console then you will get 'undefined' as a result as the statement doesn't evaluate to any returned value. But the variable will have a true or false value.

    Here are some examples where I just execute the statement without assigning the result to a variable:

    This is what happens if we do assign the result:

  • 0

    thanx chris, it works , guess it was the metadata reset that resolved the issue. Just wondering how can i modify the stack convert opportunity handler, alert to my own alert function, if No Company or Person selected. Cannot Continue with Conversion.

  • 0

    I guess all you would need to do is to *not* call wsLead.ValidateCompanyEntry but do your own validation at that point. It's a pretty simple function:

    ValidateCompanyEntry: function(bUseCompanies) {

    var validationOK = true;
    if (document.forms.EntryForm.HIDDENPERSONID.value == "0") {
    if (bUseCompanies) {
    if (document.forms.EntryForm.HIDDENCOMPANYID.value == "0") {
    validationOK = false;
    }
    }
    }
    if (!validationOK) {
    alert(msgNoConvert);
    }
    return validationOK;
    }

    ...but you can see that the alert() is built in to the function itself. Just write your own version with your own dialog box code.

  • 0

    Excellent will try this approach