Announcement

Collapse
No announcement yet.

signal object triggers @relate

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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:	292
Size:	21.7 KB
ID:	96687

  • #2
    Hi Maarten, I believe it's not possible to access it from formula.

    Comment


    • #3
      Hi Maarten,

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

      Comment


      • #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


        • #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


          • #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.

          • #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


            • #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:	233
Size:	24.2 KB
ID:	96750

              These are the relationships:

              Click image for larger version

Name:	image.png
Views:	195
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

            • #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


              • #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


                • #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


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

                    Comment


                    • #13
                      Originally posted by Maarten View Post
                      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


                      • #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...
                      X