function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Aron Schor 24Aron Schor 24 

Assistance with Trigger that updates multiple records

Hi,

I have a trigger that updates a currency field on a custom object (Pitch).  The amount reflects the Sum of Opportunty Amounts among all Pitch records that have the same Property group.  However, it can only update the one record that triggers it.  I really want to update all the Pitch records that have the same property group so all records would then have the same value.  I get an error when doing the other records.  I am trying to use ChatGPT but am stuck.  Let me know of any suggestions.

Error when updating a record

CalculatePropertyGroupAmountBefore4: Execution Of BeforeUpdate Caused By: System.DmlException: Update Failed. First Exception On Row 0 With Id A0a1O00000cd3zEQAQ;

First Error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CalculatePropertyGroupAmountBefore4: Execution Of BeforeUpdate Caused By: System.DmlException: Update Failed. First Exception On Row 0 With Id A0a1O00000cd3zdQAA;
First Error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CalculatePropertyGroupAmountBefore4: Execution Of BeforeUpdate Caused By: System.DmlException: Update Failed. First Exception On Row 0 With Id A0a1O00000cd3zEQAQ;
First Error: SELF_REFERENCE_FROM_TRIGGER, Object (id = A0a1O00000cd3zE) Is Currently In Trigger CalculatePropertyGroupAmountBefore4, Therefore It Cannot Recursively Update Itself: [] Trigger.CalculatePropertyGroupAmountBefore4:

Line 45, Column 1: [] Trigger.CalculatePropertyGroupAmountBefore4:
Line 45, Column 1: [] Trigger.CalculatePropertyGroupAmountBefore4:
Line 45, Column 1

Trigger CalculatePropertyGroupAmountBefore4 on Pitch__c (before insert, before update) {
  // Check if the trigger is currently running.
  //if (Trigger.isRunning) {
    //return;
  //}

  // Get the records that are being triggered on.
  List<Pitch__c> records = Trigger.new;

  // Get the property group amount for each record.
  for (Pitch__c record : records) {
    List<AggregateResult> propertyGroupAmounts = [
      SELECT SUM(Opportunity__r.Amount)
      FROM Pitch__c
      WHERE Id = :record.Id OR     
     Property_Group__c = :record.Property_Group__c
      GROUP BY propertyhighspot__r.Property_Group_Text__c
    ];

    // Set the property group amount for each record.
    if (propertyGroupAmounts != null && propertyGroupAmounts.size() > 0) {
      record.Property_Group_Amount__c = (Decimal)propertyGroupAmounts[0].get('expr0');
    } else {
      // Set the property group amount to 0 if there is no amount.
      record.Property_Group_Amount__c = 0;
    }
  }

  // Update all records with the same value for Property_Group__c.
  for (Pitch__c record : Trigger.new) {
    if (record.Property_Group__c != null) {
      // Get all records with the same value for Property_Group__c.
      List<Pitch__c> matchingRecords = [
        SELECT Id, Property_Group_Amount__c, IsUpdated__c
        FROM Pitch__c
        WHERE Property_Group__c = :record.Property_Group__c
        AND Id != :record.Id
      ];

      // Update the property group amount for all matching records.
      for (Pitch__c matchingRecord : matchingRecords) {
        if (!matchingRecord.isUpdated__c) {
          matchingRecord.Property_Group_Amount__c = record.Property_Group_Amount__c;
          matchingRecord.isUpdated__c = true;
          update matchingRecord;
        }
      }
    }
  }
}
Prateek Prasoon 25Prateek Prasoon 25
Based on the error message you provided, it seems that you are encountering a recursion issue in your trigger. The error message "SELF_REFERENCE_FROM_TRIGGER" indicates that you are trying to recursively update the same record within the same trigger, which is not allowed.
One way to resolve this issue is to use a different approach that avoids the recursion. Here's a modified version of your trigger that avoids recursion by using a static boolean variable to keep track of updates:
CalculatePropertyGroupAmountBefore4 on Pitch__c (before insert, before update) {
    // Check if the trigger is currently running.
    if (Trigger.isRecursive) {
        return;
    }
    // Set a static boolean variable to indicate that the trigger is running.
    Trigger.isRecursive = true;
    // Get the records that are being triggered on.
    List<Pitch__c> records = Trigger.new;
    // Get the property group amount for each record.
    for (Pitch__c record : records) {
        List<AggregateResult> propertyGroupAmounts = [
            SELECT SUM(Opportunity__r.Amount)
            FROM Pitch__c
            WHERE Id = :record.Id OR Property_Group__c = :record.Property_Group__c
            GROUP BY Property_Group__c
        ];
        // Set the property group amount for each record.
        if (propertyGroupAmounts != null && propertyGroupAmounts.size() > 0) {
            record.Property_Group_Amount__c = (Decimal)propertyGroupAmounts[0].get('expr0');
        } else {
            // Set the property group amount to 0 if there is no amount.
            record.Property_Group_Amount__c = 0;
        }
    }
    // Update all records with the same value for Property_Group__c.
    List<Pitch__c> matchingRecordsToUpdate = new List<Pitch__c>();
    for (Pitch__c record : records) {
        if (record.Property_Group__c != null) {
            // Get all records with the same value for Property_Group__c.
            List<Pitch__c> matchingRecords = [
                SELECT Id, Property_Group_Amount__c
                FROM Pitch__c
                WHERE Property_Group__c = :record.Property_Group__c
                AND Id != :record.Id
            ];
            // Update the property group amount for all matching records.
            for (Pitch__c matchingRecord : matchingRecords) {
                matchingRecord.Property_Group_Amount__c = record.Property_Group_Amount__c;
                matchingRecordsToUpdate.add(matchingRecord);
            }
        }
    }
    // Update all matching records outside of the trigger context.
    if (!matchingRecordsToUpdate.isEmpty()) {
        update matchingRecordsToUpdate;
    }
    // Reset the static boolean variable to indicate that the trigger has completed.
    Trigger.isRecursive = false;
}

In this modified version, we use a static boolean variable Trigger.isRecursive to keep track of whether the trigger is running to avoid recursion. We also update all matching records outside of the trigger context using update DML statement after the trigger has completed, to avoid triggering the same trigger again and causing recursion.

If you find this answer helpful, Please mark it as the best answer.
Aron Schor 24Aron Schor 24
Hi Prateek, I get error Error: Compile Error: Variable does not exist: isRecursive at line 3 column 9.  I have tried looking into this more but no luck, such https://developer.salesforce.com/forums/?id=906F0000000Qtw4IAC.  Thanks.
Aron Schor 24Aron Schor 24
Actually, I got that error resovled but now I get this error:
CalculatePropertyGroupAmountBefore4: execution of BeforeUpdate

caused by: System.ListException: Duplicate id in list: a0a1O00000cd3zEQAQ
Trigger.CalculatePropertyGroupAmountBefore4: line 47, column 1