WebToLeadForm set relate field

@pgr

I am on SuiteCRM v7.12.4

When I compared my code for InlineEditing.php to the GitHub code from the link above, I had what was shown plus a Fix #9408, so I think I am current.

And for LeadFormBase.php I have the code shown as additional code in Fix #6498 plus some additional lines, so again, I think I am current.

Here is the issue I see:

In pretty much every other scenario, when the User is presented with a “Select” option, that brings up another window which then lets you choose the item you want. You “Select” your choice by clicking on one of the items shown.

When you go to Convert a Lead which has an Account Name already entered, the system presents you with a Window that shows the data already entered. You click Save and another window is presented asking you to confirm the Account Name.

I would prefer that if there were one and only good match for the Account Name that the system just proceeds without the Confirm window.

I will have an administrator process the leads and given that the administrator has many other activities at any point in time, being presented with another window that appears to present options has the potential for creating issues/confusion/mistakes.

However, if the architects want it confirmed, then I have an issue with how it is being confirmed.

In every other scenrio I can think of in SuiteCRM, when the user is presented with a Select option, they click on Select, another Window is presented and from the choices presented, the user clicks on one and it is used as the entry.

For the window presented in the Convert Lead Account Name confirmation, there are two choices presented:

  • Select
  • the Account Name

The expectation is that the use clicks Select to agree to use the Account Name already showing.

This is against every other use of Select in SuiteCRM

If the User clicks the Account Name being shown (thinking they are choosing that, like they do for all other uses of Select), they are taken to the Account Window, with no indication why they are there.

I guarantee that an administrator doing this on an occasional basis will get this wrong sometimes and will likely try to avoid processing leads for fear of making an error - not something I want to see.

Is there a code change I could make - I know it would not be upgrade safe - that would NOT present the “Confirm Account Name” screen if the Account Name given matches one and only one existing Account Name? Instead, the system processes the data as given?

I appreciate your help

I don’t fully understand your issue, so let me try advancing an explanation and then you can tell me if I am on the right track or not…

I think that conversion screen is not very well designed and causes confusion:

image

:point_up: if the Box is checked, the fields below will be used for a new records creation, and the “OR Select Contact” block should be grayed out (as in my altered image, but not in SuiteCRM).

image

:point_up: if the Box is unchecked, then things are more intuitive: the fields below collapse and disappear, and it’s easier to understand that the “OR Select Contact” block is there for you to pick a Contact from the list of existing records.

Does this help?

@pgr

The issue I have is with the Account selection

If I have entered a valid Account Name in my form, and it is not only valid but is the ONLY Account that matches that name, then I would like the Account selection to have that name pre-entered in the Convert Lead window, and used without additoinal confitmation other than Save.

If I am pre-entering the Account name - say in a hidden field in the Contact form - then I have made that check and I don’t want the sytem second guessing that and presenting confusing choices to the user/administrator.

So when I click “Convert Lead”, ideally, the pop-up window reflects all the data submitted by the form - including any hidden fields I used - and if the user clicks Save, it accepts what is there - assuming the Account Name is a match and the only match for an existing Account.

If the Account Name is not a match or there are multiple matches, then yes, ask more questions and require more choosing.

I did find an old Sugarv6 developer post that showed how to add a relate field to a List view

It is NOT upgrade safe but it may give some clues as to how to pre-populate for a Contact and have the Account selection work, but I need time to dig into that before I can see if it would work.

I do agree with you. Having the Lead be the feed from a Contact form is better since it can be highlighted for users/admins, but that interface is stopping me from using it.

I just tried creating a new Lead, using an existing Account name (“SuperG Tech”).

Then I converted the lead and immediately clicked Save without changing anything on the conversion screen.

SuiteCRM shows me this:

image

If I click the Select link, I get the behaviour you want. It’s only one more click, and not much to type or think about - so I guess users could learn this easily…

Having that confirmation screen makes sense, I guess. There might be cases where the options are more dubious.

I do think that graphically, the screen emphasizes Create account a lot more than Select… maybe I would just change that with some custom CSS if I wanted my users to go for the Select most of the times.

@pgr

I agree, that is the interface I see when converting a lead

See my comments earlier about why I think the use of Select in that interface is inconsistent with the use of Select throughout the rest of SuiteCRM and why it will be causing confusion and potential problems with users/admins who only occasionally use this feature.

That is why I am looking at directing WebToForm to Contacts, not leads, and looking at some hidden field use to differentiate Contacts created that way.

Ok, now I understand your previous texts better, now that I am thinking of the same dialog window as you :slight_smile:

I agree that the word Select in that confirmation window is wrong and inconsistent - it could simply be Use this one.

And the other fields shown on that list, instead of being links taking you to the Account detail record, could be shown without being links, and then an additional action button on each row could be used explicitly saying “View account”.

If you want to try tweaking that behaviour, or that design and the labels, it’s here:

And I found a nice description of how to customize that file here:

Be careful because that code is probably also used from other places in the app (duplicate checks, for example).

@pgr

VERY helpful, thank you

And you showed me how to do it in a upgrade safe way - even better :slight_smile:

I’ve got a couple of things on the go right now but want to take a shot at this soon so I’ll update this post when I do

Thnaks again!

@pgr

Getting there, but need some guidance

I have looked into the …/modules/Accounts/AccountBaseForm.php file and I the more I look there, the more I am convinced I want to avoid that process and instead, have the Lead accept the Account Name given if there is one and only one Account that matches the given Account Name.

If I let the process get to the point where it is calling the AccountBaseForm.php file, then the interaction is going to create issues.
If the Account Name is entered and the user clicks Save on the Convert Lead form, they are presented with a window that has TWO large “CREATE ACCOUNT” buttons, and one tiny “Select” link. I could change the text in the “Select” link, but the visual implication is to CREATE a new account, and if the user clicks on “CREATE ACCOUNT”, the system will create a duplicate account with the same name.

SO I looked at …/modules/Leads/LeadBaseForm.php and I think that is where I want to make edits and avoid the whole account confirmation dialog.

In the LeadBaseForm.php file, lines 215-253, the code checks if there is one and only one Account that matches the Account Name provided. If so, the code fetches the corresponding Account ID.

So if the code has an Account ID, my condition is fulfilled and I now want to just accept the Account as given and Convert the Lead to a Contact under that Account - WITHOUT going through the AccountBaseForm.php check step.

It looks to me like lines 371-379 are where LeadBaseForm.php decides how to save the Lead. But i cannot follow the logic there.

Is there a way that I can edit the code in LeadBaseForm.php so that if I get to line 371 and have an Account ID set, I can just Convert and Save the Lead as a Contact under the Account given?

If so, I’ll test it on the core code and then, assuming it works, return the core code to its original version and use the technique above to do this in an upgrade-safe way and post back here the final solution.

Hoping we are close …

R

@pgr

I have figured out that in the Convert Lead form, if I can populate the field to the right of the “Create Account OR Select Account” label with the Account Name, then the system will save the Lead without the Account Name check.

This is true IF the Account Name given matches one and only one Account, which is what I want.

However, I cannot see where that field is even displayed let alone how to insert a value.

I know the value I want to insert : $leadBean->account_name

I just do not know where to insert it.

Any ideas?

(It’s not called LeadBaseForm.php, but LeadFormBase.php - no wonder I wasn’t finding it when searching)

Your last suggestion, filling in the field beforehand, that would be in a totally different part of the code, when generating the screen, probably it’s
modules/Leads/views/view.convertlead.php
display() function

You can re-use the code from the other file, handleLeadAccountName function (I wrote that, BTW :blush: ) to get the account_id and check if it’s a single result. Adapt the logic to your needs.

@pgr

Sorry about that, I think I am getting dyslexic ; glad you figured out I was being an idiot

As for letting me know you were the author of the “handleLeadAccountName” function, was that to make sure I did not criticize it? :slight_smile:
Seriously, it was one of the cleanest functions I have seen in the SuiteCRM/SugarCRM code: Well documentd and logically presented.

Unfortunately, I think I have exceeded my abilities here. I am going in circles. I go to one piece of code which refers me to another peice of code which …

I am sure it is good coding practice to keep the code modular and reusable but I am having a devil of a time tracing it.

When I looked at the display() function in “modules/Leads/views/view.convertlead.php”, I thought I found what I was looking for in lines 462-466 where the code comments said it was to “//link selected account to lead if it exists”.

I tried adding a line with
$lead->account_name = $selectedBeans[‘Accounts’]->name;
(guessing at variable names)

but no effect.

I looked at other code but could not see where the field to the right of “Create Account OR Select Account” in the ConvertLead pop-up was even shown, let alone how to populate it.

So as I said, it has got to the point where it is beyond my pay-grade …

I appreciate the guidance you have provided. I think we are close, but as they say, close only counts in horseshoes.

So for me, unless you have a suggestion (not expecting but would be thrilled if you did), then I am back to using WebForm to Contact, not Lead.

Thank you for your help.

That convert lead screen is a bloody mess, I really dislike that code. I also have difficulty following it, I’d have to really go into debugging mode and step through it.

Maybe a dirty hack in LeadFormBase is your best option, or in
modules/Leads/tpls/ShowDuplicates.tpl
and the corresponding
modules/Leads/views/view.showduplicates.php

Something like injecting a bit of Javascript to “click” the Select field automatically for you, in the cases where there is only one row.

this is the bit of HTML that handles the form submit:

A similar action executed immediately after the page loads would have the same effect, I guess.

If you edit tpl files remember to clear the cached versions in
/cache/smarty/templates_c/

@pgr

I tried to find the file where you showed the html that handled the form submit and could not find it.

I even tried doing
grep -R "document.forms['dupContacts'].selectedContact.value" {SuiteCRM_Directory}
and came up empty

I am now on SuiteCRM 7.12.5

But here is what I have found.

If, in the window presented when you click “Convert Lead” from the “Actions” dropdown when viewing an existing lead, if you manually enter the Account Name in the field to the right of
" Create Account OR Select Account * "
and if that Account Name matches one and only one Account in the system
the Convert Lead choice is processed without any further check
which is exactly what I want

So I figured that if I could, in the code, insert the Account Name into that field when there was one and only one match to the Account Name entered with the Lead, I have what I want.

So, in line 199 of modules/Leads/views/view.convertlead.php is the code

    if ($module == "Accounts" && $field == 'name') {
        $focus->name = $this->focus->account_name;
		...

and that puts the Account Name entered with the Lead into the field just below the field to the right of
" Create Account OR Select Account * "

Since that if condition will only evaluate to true if there is one and only one matching Account Name, so in that same if condition that already exists set the value “$this->focus->account_name” into field to the right of
" Create Account OR Select Account * "
and I have what I want.

However …
I cannot find where the field to the right of " Create Account OR Select Account * " is displayed in modules/Leads/views/view.convertlead.php so I cannot see where or how to set it

I am hoping it is as simple as adding another
smarty->assign( ??? , $this->focus->account_name );
line of code within the if statement
But I cannot determine what the smarty variable name is for the field to the right of " Create Account OR Select Account * "
(or for that matter, if there is a smarty->assign variable available for that field)

Is there a way to determine what the smarty->assign variable name would be for the field to the right of " Create Account OR Select Account * " (or if there is such a variable)?

I don’t know the answers, but here is are some tips to help you sort things out…

The reason that this Smarty construction is complex is because

  1. module is typically used from a variable. Basically, the convert screen is almost a generic screen to copy over data from any module to any module.

  2. Contacts, Leads, Users and Accounts are often all encompassed in a concept called “Person”

  3. The convert form seems to reuse code from “Find duplicates” feature…

So for example, your grep didn’t catch it, because this is how it’s written generically:

→ SuiteCRM/PersonFormBase.php at master · salesagility/SuiteCRM · GitHub

If you ask me, this is a great example of how not to do things, just more levels of abstraction without much gain and with incredibly increased complexity…

This is the grep I used to find it:

grep -irn 'document.forms' . | grep '.selected'

By searching only for bits that don’t include the module name. And then narrowing it down with further greps, once I spot what I want:

grep -irn 'document.forms' . | grep '.selected' | grep Person


Another tip: go look at the compiled Smarty template, somewhere under
/cache/smarty/templates_c/

This should be a PHP file with a randomly generated name, but part of the name is recognizable, so you can find the one you need. This might help you understand where it’s getting the values from, and how you should try the assign.

I think the one you want is the footer, something like

/cache/smarty/templates_c/%%9E^9E1^9E117A0A%%ConvertLeadFooter.tpl.php

@pgr

I have it working!

If you see that I have done something that you think may cause me problems down the road, PLEASE let me know.

What I wanted was to have the act of Converting a Lead that had an Account Name entered (which I will do via hidden fields in my WebToLeadForm) process the “Save” without a need for the user to confirm the Account Name if the Account Name provided with the Lead exactly matches one and only one existing Account Name in the system.

To do that, I made edits to the modules/Leads/views/view.convertlead.php file - in the custom directory to make it upgrade safe - and used your method handleLeadAccountName($lead) in modules/Leads/LeadFormBase.php to do the check if there was an exact one and only one match. Thank goodness you created that method as a static function, letting me acccess it as I did.

Here is what I did

cd {SuiteCRM_directory}
mkdir -p custom/modules/Leads/views
cp -a modules/Leads/views/view.convertlead.php custom/modules/Leads/views/view.convertlead.php 
nano --linenumbers custom/modules/Leads/views/view.convertlead.php

Change

 364         if (!empty($_REQUEST['record'])) {
 365             $lead = BeanFactory::newBean('Leads');
 366             $lead->retrieve($_REQUEST['record']);
 367         }
 368
 369         global $beanList;
 370         $this->loadDefs();
 371         $beans = array();
 372         $selectedBeans = array();
 373         $selects = array();
 374
 375         // Make sure the contact object is availible for relationships.
 376         $beans['Contacts'] = BeanFactory::newBean('Contacts');

To

 364         if (!empty($_REQUEST['record'])) {
 365             $lead = BeanFactory::newBean('Leads');
 366             $lead->retrieve($_REQUEST['record']);
 367         }
 368
 369         // This creates a different way of handling conversion of Leads to Contacts
 370         // when the Lead has an Account Name entered
 371         // and the Lead Account Name matches exactly one and only one existing Account Name
 372         // Under this condition, when the User clicks Save, this edit will skip the confirmation window
 373         // and create a Contact which is associated with the Account Name
 374         // To do this, use the method handleLeadAccountName($lead) in modules/Leads/LeadFormBase.php
 375         // which checks if there is one and only one matching Account Name
 376         // and if so, return the AccountID
 377         // but if not, return nothing
 378         require_once('modules/Leads/LeadFormBase.php');
 379         $relatedAccountID = LeadFormBase::handleLeadAccountName($lead);
 380
 381         global $beanList;
 382         $this->loadDefs();
 383         $beans = array();
 384         $selectedBeans = array();
 385         $selects = array();

and Change (original line numbers used)

 399         // Accounts
 400         if (!empty($_REQUEST['selectedAccount'])) {
 401             $_REQUEST['account_id'] = $_REQUEST['selectedAccount'];
 402             unset($_REQUEST["convert_create_Accounts"]);
 403             unset($_POST["convert_create_Accounts"]);

To

 411         // Accounts
 412         // This is where we use the test above
 413         // to see if one and only one Account matches the Lead Account Name
 414         // and if so, inject the AccountID into the account_id field
 415         // which "tricks" the ConvertLead code into accepting the Account Name
 416         // without going through the extra step of confirming the Account Name
 417         if (!empty($_REQUEST['selectedAccount']) || ( !empty($relatedAccountID) && $relatedAccountID != NULL && $relatedAccountID != '' ) ) {
 418             if ( !empty($relatedAccountID) ) {
 419                 $_REQUEST['account_id'] = $relatedAccountID;
 420             } else {
 421                 $_REQUEST['account_id'] = $_REQUEST['selectedAccount'];
 422             }
 423             unset($_REQUEST["convert_create_Accounts"]);
 424             unset($_POST["convert_create_Accounts"]);

Now, when a Lead includes an Account Name that exactly matches one and only one existing Account Name in the system, the “Save” command accepts the Account Name without further confirmation and converts the lead to a Contact which is associated with the Account.


SuiteCRM -> Admin -> Repair -> Quick Repair and Rebuild

Thanks for your help @pgr

Any comments for improvement?

2 Likes

Great work! :tada:

To make it upgrade-safe, you should be able to simply override the view’s display method, have a look here:

→ Views :: SuiteCRM Documentation

@pgr

I edited my post above to include instructions that make the edit upgrade-safe

I checked and modules/Leads/views/view.converlead.php is never required or included in any other file in SuiteCRM so I just copied the original file to the custom directory equivalent and made the edits there

Thanks again

1 Like

This solution is generic, isn’t it? I mean, it just works and would provide a useful feature to anyone, am I right?

I’m saying this because it could be made into a PR.

There is nothing in this solution that is unique to my situation.

Anytime a Lead with an Account Name identified is converted to a Contact, if the Account Name in the Lead matches one and only one existing Account Name in the system, when the user selects Contert Lead and then clicks Save, there will be not further confirmation check for the validity of the Account Name entered.

This is what I wanted and it does this.

If others wanted this, they have a solution that works.

If this is a feature that is wanted in the core system, then yes, it should be ready for implementation in the core.

If there is concern about having this as the defaul convert action when an Account Name is included with the Lead, then maybe add a checkbox to allow the users to decide if they want this?

I personally would always want this, but maybe others feel differently?

@pgr

I have never done a Pull Request so if you want to submit under your name, feel free.

The solution is 1/2 yours anyways :slight_smile: