signal object triggers @relate

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Maarten
    Member
    • Jun 2020
    • 56

    signal object triggers @relate

    Hi,

    I've created a workflow that is triggered by an @relate signal of a related entity Travel.

    I want to access the ID of the related Travel entity. I am using travelId. But it's not the right entity.

    Under what field can I access the travel ID in a formula script?

    Click image for larger version

Name:	image.png
Views:	296
Size:	21.7 KB
ID:	96687
  • yuri
    Member
    • Mar 2014
    • 8453

    #2
    Hi Maarten, I believe it's not possible to access it from formula.
    If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

    Comment

    • lazovic
      Super Moderator
      • Jan 2022
      • 810

      #3
      Hi Maarten,

      Can you please show the Contact, Travel and Traveler entities relationships? Maybe there will be some kind of workround.

      Comment

      • Maarten
        Member
        • Jun 2020
        • 56

        #4
        Relation between Contact and Travel:

        Click image for larger version  Name:	image.png Views:	2 Size:	15.9 KB ID:	96712

        Relation between contact and Traveler:

        Click image for larger version  Name:	image.png Views:	2 Size:	8.6 KB ID:	96713

        Relation between Traveler and Travel:

        Click image for larger version  Name:	image.png Views:	2 Size:	11.4 KB ID:	96714

        What i'm trying to do:
        1. When a Contact is related to a Travel (Listen to the @relate of the contact)
        2. Create a Traveler record, link it to both the Contact and the Travel, and set one additional field manually.

        So I need Traveler because I need to store metadata to the relationship of Contact and Travel.

        I also want to delete the Traveler record when Travel is unrelated from the Contact.
        So it's not possible to solve this problem by doing a record\FindRelatedOne() (which is a kind of sub optimal approach to the @relate workflow, but wouldn't work for the @unrelate)

        Comment

        • lazovic
          Super Moderator
          • Jan 2022
          • 810

          #5
          Maarten,

          Try to use this formula script for your workflow:
          Code:
          $travelsIds = workflow\targetEntity\attribute('travelsIds');
          $travelsCount = array\length($travelsIds);
          
          $contactId = workflow\targetEntity\attribute('id');
          
          ifThenElse(
          $travelsCount > 1,
          $travelId = array\at($travelsIds, ($travelsCount - 1)),
          $travelId = array\at($travelsIds, 0)
          );
          
          $travelerId = record\create('Traveler',
          'contactId', $contactId,
          'travelId', $travelId
          );

          But in general, the relationships between entities seems a bit wrong for this case.

          For example, if we link several Travelers to a Contact, this Contact will be linked to only one Traveler, and this is logical. You need to think carefully and figure out how to remake these relationships. Only after that, you can start reworking the first workflow with a relate signal and creating a second workflow with an unrelate signal which will delete the Traveler.

          Comment

          • Maarten
            Member
            • Jun 2020
            • 56

            #6
            lazovic, thanks for this script. Is there potential for this script to fail when there is paralization happening? Or will always the workflow\targetEntity\attribute retrieve the travelIds that are for this specific triggered workflow?

            I will have a look at the relationships, to see if they can be done differently

            Comment


            • lazovic
              lazovic commented
              Editing a comment
              This function will always get the attribute value directly for the Contact, which is a Target Entity for workflow.
          • Maarten
            Member
            • Jun 2020
            • 56

            #7
            For the Record, on Contact entity:

            The @unrelate script

            Code:
            $travelsIds = travelsIds;
            $previousTravelsIds = workflow\targetEntity\attributeFetched('travelsIds');
            
            $k = 0;
            while($k < array\length($previousTravelsIds)){
                $previousTravelsId = array\at($previousTravelsIds, $k);
                if(!array\includes(travelsIds, $previousTravelsId)){
                    $travelerId = record\findOne('Traveler', 'createdAt', 'DESC', 'personId', id, 'travelId', $previousTravelsId);
                    
                    record\delete('Traveler', $travelerId);
                }
                $k = $k + 1;
            }​
            The @relate signal script:

            Code:
            $travelsIds = travelsIds;
            $travelsCount = array\length($travelsIds);
            
            $contactId = id;
            
            ifThenElse(
            $travelsCount > 1,
            $travelId = array\at($travelsIds, ($travelsCount - 1)),
            $travelId = array\at($travelsIds, 0)
            );
            
            $travelerId = record\create('Traveler',
            'personId', $contactId,
            'travelId', $travelId
            );​

            Comment

            • Maarten
              Member
              • Jun 2020
              • 56

              #8
              lazovic,

              Would you be able to help me understand this mystery behavior?

              This is the workflow for @relate on Contact.

              It finds the travelId. It creates a notification to myself with the travelId, and I get the travelId returned.

              But when it creates the Traveler, the travelId is empty.

              Click image for larger version

Name:	image.png
Views:	238
Size:	24.2 KB
ID:	96750

              These are the relationships:

              Click image for larger version

Name:	image.png
Views:	197
Size:	12.4 KB
ID:	96751​​

              Comment


              • rabii
                rabii commented
                Editing a comment
                on the create record > traveler
                make sure you only use formula OR only assisted fields, it doesn't work when you use both.
                I have tested this and the variables pass but when only use the formula
            • lazovic
              Super Moderator
              • Jan 2022
              • 810

              #9
              Maarten,

              Please tell me the value of the personId field for the created Traveler is filled in in this case as it should?

              Please note that variables defined within formula won't be passed back, they are only available within a current script.

              Comment

              • Maarten
                Member
                • Jun 2020
                • 56

                #10
                I think I figured out what is going wrong.

                The script you proposed:

                Code:
                ifThenElse(
                $travelsCount > 1,
                $travelId = array\at($travelsIds, ($travelsCount - 1)),
                $travelId = array\at($travelsIds, 0)
                );
                ​
                It assumes the travelIds are sorted chronologically, where the last entry is the last in the array. But it's not the case. They are random.

                There should be a better way to get the ID of the related record that triggers the @relate signal? Otherwise, what's the point of having an @relate signal?

                Comment

                • Maarten
                  Member
                  • Jun 2020
                  • 56

                  #11
                  I'm still quite puzzled. This formula script works perfectly when I use the formula Sandbox on the Entity Travel

                  Code:
                  $travelersCount = array\length(travelerIds);
                  
                  $k = 0;
                  while($k < $travelersCount){
                      $travelerId = array\at(travelerIds, $k);
                      $found = record\findRelatedOne('Travel', id, 'travelers', 'createdAt', 'desc', 'personId', $travelerId);
                      
                      if($found == null){
                          record\create('Traveler', 'travelId', id, 'personId', $travelerId);
                      }
                      
                      $k = $k + 1;
                  }​
                  But the exact same code doesn't work when I create a workflow for the entity Travel that is triggered by the Signal @relate.traveler

                  The id of Travel can be used to create a notification, but it can't be used to populate the 'travelId' field in Traveler record.

                  Comment

                  • Maarten
                    Member
                    • Jun 2020
                    • 56

                    #12
                    This particular problem was solved by recreating the relationship between Traveler and Travel. Somehow it got corrupted

                    Comment

                    • rabii
                      Active Community Member
                      • Jun 2016
                      • 1250

                      #13
                      Originally posted by Maarten
                      For the Record, on Contact entity:

                      The @unrelate script

                      Code:
                      $travelsIds = travelsIds;
                      $previousTravelsIds = workflow\targetEntity\attributeFetched('travelsIds');
                      
                      $k = 0;
                      while($k < array\length($previousTravelsIds)){
                      $previousTravelsId = array\at($previousTravelsIds, $k);
                      if(!array\includes(travelsIds, $previousTravelsId)){
                      $travelerId = record\findOne('Traveler', 'createdAt', 'DESC', 'personId', id, 'travelId', $previousTravelsId);
                      
                      record\delete('Traveler', $travelerId);
                      }
                      $k = $k + 1;
                      }​
                      The @relate signal script:

                      Code:
                      $travelsIds = travelsIds;
                      $travelsCount = array\length($travelsIds);
                      
                      $contactId = id;
                      
                      ifThenElse(
                      $travelsCount > 1,
                      $travelId = array\at($travelsIds, ($travelsCount - 1)),
                      $travelId = array\at($travelsIds, 0)
                      );
                      
                      $travelerId = record\create('Traveler',
                      'personId', $contactId,
                      'travelId', $travelId
                      );​
                      i think you had an issue is this part @relate signal, it should be

                      PHP Code:
                      $travelerId = record\create('Traveler',
                      'contactId', $contactId,
                      'travelId', $travelId
                      );​​ 
                      
                      contactId instead of personId because the relationship field is based on the field name and not the label (Person) was just a label for the foreign link field.
                      Rabii
                      Web Dev

                      Comment

                      • Maarten
                        Member
                        • Jun 2020
                        • 56

                        #14
                        rabii, thanks for thinking along!

                        This is the Traveler object API response:

                        Code:
                        {
                            "id": "-------------",
                            "name": "----------------",
                            "deleted": false,
                            "description": null,
                            "createdAt": "2023-08-24 07:27:39",
                            "modifiedAt": "2023-08-24 07:27:39",
                            "sharepointListId": null,
                            "createdById": "614da7c0e68dba891",
                            "createdByName": "----------------------------",
                            "modifiedById": null,
                            "modifiedByName": null,
                            "assignedUserId": null,
                            "assignedUserName": null,
                            "teamsIds": [],
                            "teamsNames": {},
                            "forecastRoleId": null,
                            "forecastRoleName": null,
                            "personId": "63ff677edf94fcc4f",
                            "personName": "------------------",
                            "travel1Id": "64e6118e0c94e5907",
                            "travel1Name": null,
                            "isFollowed": false,
                            "followersIds": [],
                            "followersNames": {}
                        }​
                        So I guess using personId is not the error.

                        Comment


                        • rabii
                          rabii commented
                          Editing a comment
                          you should differentiate between what the api returns and what espocrm formula script use as (attributes) if you go to the entity Traveler formula and try to type in person (i am sure the autocomplete will not return any field / attribute but if you type in contact the autocomplete will list contact attributes). i have tried your set up on my local instance and issue was with personId - where contactId was the correct.
                      Working...