Automatic Lead Assignment Workflow Stuck - Assistance Needed

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • CamiReyes
    Junior Member
    • Apr 2025
    • 7

    #1

    Automatic Lead Assignment Workflow Stuck - Assistance Needed

    My automatic lead assignment workflows are stuck. I'm encountering a "Could not parse" formula error in the logs (example: [2025-05-15 08:54:08] ERROR: (500) Process 6825abb0511d76d15 formula error: Could not parse.).

    Qualified Leads: The workflow gets stuck at a Gateway after attempting external user assignment. The diagram is attached.

    Unqualified Leads: This workflow assigns to the "teams" (Many-to-Many relationship) field but doesn't reach the End Event.

    I'm using PHP Script Tasks for assignment logic. Any ideas on what could be causing this persistent formula parsing error, especially in the context of Gateways or when working with Many-to-Many relationships?

    Thanks for any help!
    Attached Files
    Last edited by CamiReyes; 05-15-2025, 09:00 AM.
  • lazovic
    Super Moderator
    • Jan 2022
    • 1013

    #2
    Hi CamiReyes,

    Please copy the code of all formula scripts in your flowchart and paste it into the post. This way we can figure out the problem.

    Comment

    • CamiReyes
      Junior Member
      • Apr 2025
      • 7

      #3
      Thanks for your reply!!! lazovic

      First flowchart

      Conditional start event:

      cCRenta != "Menos de $800.000" &&
      cCRenta != "$800.000 a $1.000.000" &&
      cCEdad >= 20 &&
      cCEdad <= 50

      1st Script task:
      // Obtener el lead actual
      $lead = $process->get('targetRecord');

      // Buscar usuarios Externos activos que cumplan las condiciones
      $externos = $this->getEntityManager()
      ->getRepository('User')
      ->where([
      'teamId' => '682427b3d25d84242', // Reemplaza con el ID real
      'isActive' => true,
      'title!=' => $lead->get('cCSistemaDeSalud'),
      'cDailyLeadsAssigned<' => 2
      ])
      ->find();

      // Si hay usuarios disponibles, asignar el lead al primero
      if (!empty($externos)) {
      $user = $externos[0];
      $lead->set('assignedUserId', $user->getId());
      $this->getEntityManager()->saveEntity($lead);
      $process->set('assignedUser', $user); // Guardar el usuario para usarlo luego
      }

      2nd Script task:
      $user = $process->get('assignedUser');
      $currentCount = $user->get('cDailyLeadsAssigned') ?? 0;
      $user->set('cDailyLeadsAssigned', $currentCount + 1);
      $this->getEntityManager()->saveEntity($user);​

      [2025-05-15 09:12:30] ERROR: (500) Process 6825affeef258909c formula error: Could not parse.

      Second flowchart

      Conditional start event:

      ​cCRenta == "Menos de $800.000" ||
      cCRenta == "$800.000 a $1.000.000" ||
      cCEdad < 20 ||
      cCEdad > 50​

      Script task:
      ​$lead = $process->get('targetRecord');
      $teamEjecutivoId = "682427bd62784e807"; // Reemplaza con el ID real
      $lead->set('teamsIds', [$teamEjecutivoId]);
      $this->getEntityManager()->saveEntity($lead);​

      ERROR: (500) Process ... formula error: Attribute name [$teamEjecutivoId] contains not allowed characters.

      Comment

      • lazovic
        Super Moderator
        • Jan 2022
        • 1013

        #4
        CamiReyes,

        Please note that in the Execute Formula Script action or in the Script Task element you need to enter the EspoCRM formula script, not the PHP code. More about the formula script you can find here: https://docs.espocrm.com/administration/formula.

        Comment

        • CamiReyes
          Junior Member
          • Apr 2025
          • 7

          #5
          thanks again lazovic

          Made changes and I keep getting this error:

          Unknown function: empty

          even though I’ve removed every call to empty() from my scripts. I’ve also cleared the cache and restarted the workflows, but the error still appears on every new lead.

          Here are my current configurations:

          First flowchart – Conditional start event expression

          Code:
          cCRenta != "Menos de $800.000" &&
          cCRenta != "$800.000 a $1.000.000" &&
          cCEdad >= 20 &&
          cCEdad <= 50
          Script Task #1 (Execute Formula Script):

          Code:
          $healthSystem = workflow\targetEntity\attribute('cCSistemaDeSalud' );
          $externos = record\findMany(
          'User', 1,
          'cDailyLeadsAssigned', 'asc',
          'teamId=', '682427b3d25d84242',
          'isActive=', true,
          'title!=', $healthSystem,
          'cDailyLeadsAssigned<', 2
          );
          if (array\length($externos) > 0) {
          $userId = array\first($externos);
          record\update(
          'Lead',
          workflow\targetEntity\attribute('id'),
          'assignedUserId',
          $userId
          );
          $$assignedUserId = $userId;
          }

          Script Task #2 (Execute Formula Script):​

          Code:
          $userId = $$assignedUserId;
          $currentCount = record\attribute('User', $userId, 'cDailyLeadsAssigned') ?? 0;
          record\update(
          'User',
          $userId,
          'cDailyLeadsAssigned',
          $currentCount + 1
          );

          Second flowchart – Conditional start event expression

          Code:
          cCRenta == "Menos de $800.000" ||
          cCRenta == "$800.000 a $1.000.000" ||
          cCEdad < 20 ||
          cCEdad > 50

          Script Task (Execute Formula Script) for special leads:​

          Code:
          $teamEjecutivoId = "682427bd62784e807";
          entity\addLinkMultipleId('teams', $teamEjecutivoId);
          ​
          Everything else is pure Formula Script—no PHP, no empty(). Yet the log still shows:​

          Code:
          ERROR: Workflow <ID>: Action failed, startBpmnProcess 0, Unknown function: empty.
          Could there be a hidden call to empty(), or am I missing something in the syntax? Thanks in advance for any pointers!​

          How could I configure all this to correctly assign leads under these conditions? I'm very lost

          ​​
          Last edited by CamiReyes; 05-15-2025, 07:58 PM.

          Comment

          • lazovic
            Super Moderator
            • Jan 2022
            • 1013

            #6
            CamiReyes,

            Try to remove processes (processes, not flowcharts) that are running ({ESPO_URL}/#BpmnProcess). Then, make a rebuild in the Administration.

            In addition, the formula script itself needs to be corrected, for example, the array\first() function is missing in EspoCRM.

            Comment

            • CamiReyes
              Junior Member
              • Apr 2025
              • 7

              #7
              lazovic

              First of all, thank you again for your previous help — I’ve made great progress thanks to your guidance.

              I’m on EspoCRM 9.0.8 with the Advanced Pack, and I believe I’m very close to finishing, but I’ve hit one last issue. I created a custom PHP service (LeadAssignment.php), and I’m trying to call it from a Script Task using:

              Code:
              record\script('LeadAssignment', 'assign');
              But I get this error in application.log:

              Code:
              Unknown function: record\script
              I also can't find the “Allow Custom Scripts Execution” setting under Admin > Settings > Flowchart. I only see standard task types (Script Task, User Task, Call Activity, etc.), and no option to define a Service Method in Script Tasks.

              Should I be using a Call Activity instead? Or is there another way to execute my script on /public_html/custom/espo/custom/services/LeadAssignment.php within the flowchart?

              Any insight would be a huge help — I think this is the final step I’m missing.

              Thanks again!

              Comment

              • lazovic
                Super Moderator
                • Jan 2022
                • 1013

                #8
                CamiReyes,

                You can see the list of available functions for the formula script here: https://docs.espocrm.com/administrat...ula/#functions.

                If you want to run some custom PHP script, it is best to create a custom action service for workflows and flowcharts:
                https://docs.espocrm.com/administrat...service-action,
                https://docs.espocrm.com/development...ervice-actions.

                But you can clarify what exactly you want to achieve, and perhaps this can be done with a regular Espo formula script or with workflow/flowchart actions.

                Comment

                • CamiReyes
                  Junior Member
                  • Apr 2025
                  • 7

                  #9
                  Thanks again for the quick reply!

                  What I’m trying to achieve is custom lead assignment logic within a flowchart. I need to assign a lead to a user based on specific conditions:

                  - Lead is "qualified" if age is between 20 and 50, and income is not in two specific ranges.
                  - If qualified:
                  - If the “insurance type” field has a value → assign to team "Extseguros"
                  - If it's empty → assign to team "Externo"
                  - Users must:
                  - Be active
                  - Have received fewer than 2 leads today
                  - Have a different title than the lead’s health system
                  - If no suitable user is found → assign to the "Ejecutivo" team as fallback
                  - If not qualified → assign directly to "Ejecutivo"
                  - Some users in the "Ejecutivo" team can only receive leads with no insurance type

                  This logic seemed too complex for formula scripts, so I created a PHP class in `/custom/Espo/Custom/Services/LeadAssignment.php`.

                  Here’s the code I'm working with:

                  Code:
                  ```php
                  <?php
                  
                  namespace Espo\Custom\Services;
                  
                  use Espo\ORM\Entity;
                  
                  class LeadAssignment extends \Espo\Core\Templates\Services\Base
                  {
                  public function assign($params)
                  {
                  $leadId = $params['targetId'];
                  $entity = $this->getEntityManager()->getEntity('Lead', $leadId);
                  
                  $this->getLogger()->info("[LeadAssignment] Starting assignment for Lead ID: " . $leadId);
                  
                  $isCalificado = (
                  $entity->get('cCEdad') >= 20 &&
                  $entity->get('cCEdad') <= 50 &&
                  !in_array($entity->get('cCRenta'), ['Menos de $800.000', '$800.000 a $1.000.000'])
                  );
                  
                  if (!$isCalificado) {
                  return $this->asignarAEjecutivo($entity, true);
                  }
                  
                  $tipoSeguro = $entity->get('cCTipoDeSeguro');
                  if ($tipoSeguro) {
                  $ok = $this->asignarADisponible($entity, 'Extseguros');
                  if (!$ok) {
                  return $this->asignarAEjecutivo($entity, false);
                  }
                  } else {
                  $ok = $this->asignarADisponible($entity, 'Externo');
                  if (!$ok) {
                  return $this->asignarAEjecutivo($entity, false);
                  }
                  }
                  
                  return true;
                  }
                  
                  private function asignarADisponible(Entity $entity, $teamName)
                  {
                  $this->getLogger()->info("[LeadAssignment] Searching users in team: $teamName");
                  
                  $userRepo = $this->getEntityManager()->getRepository('User');
                  $teamRepo = $this->getEntityManager()->getRepository('Team');
                  
                  $team = $teamRepo->where(['name' => $teamName])->findOne(null, ['access' => false]);
                  if (!$team) return false;
                  
                  $usuarios = $team->get('usersIds') ?: [];
                  
                  foreach ($usuarios as $userId) {
                  $user = $this->getEntityManager()->getEntity('User', $userId);
                  if (!$user || !$user->get('active')) continue;
                  
                  if ($user->get('title') === $entity->get('cCSistemaDeSalud')) continue;
                  
                  $leadsHoy = $this->getEntityManager()->getRepository('Lead')->where([
                  'assignedUserId' => $userId,
                  'createdAt>=' => date('Y-m-d 00:00:00'),
                  'createdAt<=' => date('Y-m-d 23:59:59')
                  ])->count(null, ['access' => false]);
                  
                  if ($leadsHoy >= 2) continue;
                  
                  $entity->set('assignedUserId', $userId);
                  $this->getLogger()->info("[LeadAssignment] Assigned to user ID: $userId (team $teamName)");
                  return true;
                  }
                  
                  return false;
                  }
                  
                  private function asignarAEjecutivo(Entity $entity, $permitirLimitado = false)
                  {
                  $ejecutivos = ['carol', 'nalladett', 'paula'];
                  $repo = $this->getEntityManager()->getRepository('User');
                  
                  $usuarios = $repo->where(['active' => true])->find(null, ['access' => false]);
                  $this->getLogger()->info("[LeadAssignment] Assigning from Ejecutivo team");
                  
                  foreach ($usuarios as $user) {
                  if (!$permitirLimitado && in_array($user->get('userName'), $ejecutivos)) {
                  if ($entity->get('cCTipoDeSeguro')) continue;
                  }
                  
                  $entity->set('assignedUserId', $user->id);
                  $this->getLogger()->info("[LeadAssignment] Assigned to Ejecutivo: {$user->get('userName')} ({$user->id})");
                  return true;
                  }
                  
                  return false;
                  }
                  }

                  Comment

                  • CamiReyes
                    Junior Member
                    • Apr 2025
                    • 7

                    #10
                    I’m currently calling it from a Flowchart using a Script Task, but record\script(...) throws a "Unknown function" error. I can’t find any way to run this script cleanly from a BPM diagram.

                    Would the best approach be to adapt this into a proper service action with bpmAssign($params) and trigger it from a Call Activity node?

                    I’d love to know the recommended pattern for this kind of logic in Espo.

                    Thanks again for your help!

                    Comment

                    Working...