Creating custom Validation for Lead creation using Email and CustomCountry Code.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • william34
    Junior Member
    • Jun 2023
    • 21

    Creating custom Validation for Lead creation using Email and CustomCountry Code.

    Hi, I am trying to create custom validation check with email and country for creating new Lead and Accounts.

    I have a custom field called “CustomCountry”.
    I want to allow creation of new lead and accounts only when this condition is satisfied.


    Validation Conditions
    ------------------------------------------------------------
    Email : compulsory
    CustomCountry : compulsory

    same email and same country : Not Allowed
    same email and diff country : Allowed
    ------------------------------------------------------------

    I did go through https://docs.espocrm.com/development/duplicate-check/ .

    created the file custom/Espo/Custom/Classes/DuplicateWhereBuilders/Lead.php .
    But any breakpoint on this file is never hit while creating .

    I went and set breakpoint at \htdocs\espocrm\application\Espo\Modules\Crm\Servi ces\Lead.php on function afterCreateEntity() .
    But this get hits after “The record you are creating might already exist” dialog box is appeared and “Create” is clicked.


    I would like this dialog box to only appear when validation Conditions are met.




    Please let me know how to approach it.
    much thanks,

    Click image for larger version

Name:	image.png
Views:	447
Size:	36.1 KB
ID:	94063Click image for larger version

Name:	image.png
Views:	322
Size:	68.7 KB
ID:	94064
  • lazovic
    Super Moderator
    • Jan 2022
    • 809

    #2
    Hi william34,

    Since EspoCRM v7.5 it is possible to check for duplication and validation without changes or additions to the EspoCRM code. You can try using API Before-Save script: https://docs.espocrm.com/administrat...re-save-script.

    Comment

    • william34
      Junior Member
      • Jun 2023
      • 21

      #3
      Hi @lazovic​,
      Thanks for the help,

      I looked into the Api Before-Save Script. I tested the example code, it worked.
      Based on that I came up with below formula. But it doesnt seem to be working.
      It inserts everything regardless.

      Don't know what is wrong though.


      PHP Code:
      if (entity\isNew() && !recordService\skipDuplicateCheck()) {
          
          $ids = list();
          
          
          $id = record\findOne('Lead', null, null,'emailAddress=' , emailAddress , 'customCountry=' , customCountry);
          if ($id) {
              $ids = array\push($ids, $id);
          }
      
          
          
          $ids = array\unique($ids);
      
          if (array\length($ids)) {
              recordService\throwDuplicateConflict($ids);
          }
      }

      Comment

      • rabii
        Active Community Member
        • Jun 2016
        • 1250

        #4
        hey william34

        If you want both condition to applied at once try it like this, see code below:

        PHP Code:
        
        if (entity\isNew() && !recordService\skipDuplicateCheck()) {
            $id = record\findOne('Lead', null, null, 'emailAddress=', emailAddress, 'customCountry=', customCountry);
        
            if ($id) {
                recordService\throwDuplicateConflict($id);
            }
        }
        This should work for you.
        Rabii
        Web Dev

        Comment

        • esforim
          Active Community Member
          • Jan 2020
          • 2204

          #5
          Just adding keyword for future search:

          duplicatecheck
          duplicatechecker
          duplicate check formula

          Comment

          • william34
            Junior Member
            • Jun 2023
            • 21

            #6
            hi rabii​,

            I tried the formula.

            Created new lead with name : sam , email : sam@gmail.com , customCountry : UK
            And then tried to create same Lead with same email and country. It fails in this conditions

            Same name , same email, same country : Not Allowed | Not Inserted ✅
            diff name , same email, same country : Not Allowed | Inserted ❌
            no name , same email, same country : Not Allowed | Inserted ❌
            no name , same email, diff country : Allowed | Inserted ✅



            created Lead
            name = sam , email = info@gmail.com , country = UK

            Testing Formula on ☝️ Created Lead
            name = sam , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Not Inserted | Test Passed.
            name = john , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Inserted | Test Failed.
            ​name = '' , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Inserted | Test Failed.
            ​​name = '' , email = info@gmail.com , country = US: Expected behavior = Allowed | Record Inserted | Test Passed.
            ​​​
            ​name = '' means left first name and last name blank
            Last edited by william34; 06-20-2023, 12:31 PM.

            Comment


            • rabii
              rabii commented
              Editing a comment
              i have tried the formula and it worked. what type is the customCountry ? is it an enum ?
          • rabii
            Active Community Member
            • Jun 2016
            • 1250

            #7
            what do you mean by

            Same name , same email, same country : Not Allowed | Not Inserted ✅
            diff name , same email, same country : Not Allowed | Inserted ❌
            no name , same email, same country : Not Allowed | Inserted ❌
            no name , same email, diff country : Allowed | Inserted ✅​
            Rabii
            Web Dev

            Comment


            • william34
              william34 commented
              Editing a comment
              created Lead
              name = sam , email = info@gmail.com , country = UK

              Testing Formula on ☝️ Created Lead
              name = sam , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Not Inserted | Test Passed.
              name = john , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Inserted | Test Failed.
              ​name = '' , email = info@gmail.com , country = UK : Expected behavior = Not Allowed | Record Inserted | Test Failed.
              ​​name = '' , email = info@gmail.com , country = US: Expected behavior = Allowed | Record Inserted | Test Passed.
              ​​​
              ​name = '' means left first name and last name blank


              >what type is the customCountry ? is it an enum ?
              yes its enum. with value Like : UK, US, JP
          • rabii
            Active Community Member
            • Jun 2016
            • 1250

            #8
            you should know that there is already a DuplicateWhereBuilder implemented in the crm by default for the Lead (which checks if the first or last name of the lead exist or if the emailaddress exist then the modal for duplicate check will popup) hence this checker exist it will be applied before the Befoe Save API and what you want to do is to add your code checker when the first one is triggered, meaning your code should be like below:

            PHP Code:
            
            if (entity\isNew() && recordService\skipDuplicateCheck()) {
                $id = record\findOne('Lead', null, null, 'emailAddress=', emailAddress, 'customCountry=', customCountry);
            
                if ($id) {
                    recordService\throwDuplicateConflict($id);
                }
            }​  ​ 
            
            If this doesn't work i guess you will have to disable the default one hence that one checkes for the email so it will be triggered eveytime you create a lead with an email address that another has.
            Rabii
            Web Dev

            Comment


            • william34
              william34 commented
              Editing a comment
              >you will have to disable the default

              how can I disable default
          • rabii
            Active Community Member
            • Jun 2016
            • 1250

            #9
            In this case you have to define your own duplicatewherecheck class, just follow the steps below:

            1 - Create a the new duplicatewherebuilder under espo\Espo\Custom\Classes\DuplicateWhereBuilders (file should be named Lead.php) - make sure that the folders (Classes - DuplicateWhereBuilders exist otherwise create them under the path custom\Espo\Custom) - paste in the code below:

            PHP Code:
            <?php
            namespace Espo\Custom\Classes\DuplicateWhereBuilders;
            
            use Espo\Core\ORM\Entity as CoreEntity;
            
            use Espo\Core\Duplicate\WhereBuilder;
            use Espo\Core\Field\EmailAddressGroup;
            
            use Espo\ORM\Entity;
            use Espo\ORM\Query\Part\Condition as Cond;
            use Espo\ORM\Query\Part\Where\OrGroup;
            use Espo\ORM\Query\Part\WhereItem;
            
            class Lead implements WhereBuilder
            {
                /**
                 * @param Entity $entity
                 */
                public function build(Entity $entity): ?WhereItem
                {
                    $orBuilder = OrGroup::createBuilder();
            
                    $toCheck = false;
            
                    if (
                        (
                            ($entity->get('emailAddress') || $entity->get('emailAddressData')) &&
                            (
                                $entity->isNew() ||
                                $entity->isAttributeChanged('emailAddress') ||
                                $entity->isAttributeChanged('emailAddressData')
                            )
                        ) &&
                        $entity->get('customCountry')
                    ) {
                        foreach ($this->getEmailAddressList($entity) as $emailAddress) {
                            $orBuilder->add(
                                Cond::and(
                                    Cond::equal(
                                        Cond::column('emailAddress'),
                                        $emailAddress
                                    ),
                                    Cond::equal(
                                        Cond::column('customCountry'),
                                        $entity->get('customCountry')
                                    )
                                )
                            );
            
                            $toCheck = true;
                        }
                    }
            
                    if (!$toCheck) {
                        return null;
                    }
            
                    return $orBuilder->build();
                }
            
                /**
                 * @return string[]
                 */
                private function getEmailAddressList(CoreEntity $entity): array
                {
                    if ($entity->get('emailAddressData')) {
                        /** @var EmailAddressGroup $eaGroup */
                        $eaGroup = $entity->getValueObject('emailAddress');
            
                        return $eaGroup->getAddressList();
                    }
            
                    if ($entity->get('emailAddress')) {
                        return [
                            $entity->get('emailAddress')
                        ];
                    }
            
                    return [];
                }
            }
            2 - now create the Lead.json file to map the custom class, create the file under custom\Espo\Custom\Resources\metadata\recordDefs\L ead.json (create those folder if they don't exist) and pase in the content below:

            PHP Code:
            {
                "duplicateWhereBuilderClassName": "Espo\\Custom\\Classes\\DuplicateWhereBuilders\\Lead"
            } 
            
            That is it now whene a user create a Lead the system will check if any existing lead has the same email and customCountry if yes then it will show the modal with duplicate found message otherwise nothing will show up.

            Hope this helps now, by the way if you use this code just remove the code from the formula hence you won't need it anymore.

            Enjoy
            Rabii
            Web Dev

            Comment


            • william34
              william34 commented
              Editing a comment
              Hi rabii,
              I tested it. And I was able to implement it in validation.

              Thanks for your help.

            • rabii
              rabii commented
              Editing a comment
              you are welcome
          Working...