0

I need a live synchronization between accounts and an external database. I wrote an account trigger for inserts and updates which does a callout to a script on our server. The script is called with the account Id and the needed action (insert or update).

This works well for currently created or updated accounts.

Problem is: We have some workflows and some FinancialForce magic which updates other accounts in the background when current account is inserted/updated.

So my trigger is called for all updated accounts (i.e. multiple times after save button is clicked), but I only need it for the currently displayed account.


I think a solution would be to get Id of currently displayed account and do the callout just for that account. But this code

Id currentId = apexpages.currentpage().getparameters().get('id');

seems to work only for VF pages.

So my question is: is it possible to get Id of currently displayed account (which was edited/saved by the user)? Or is there any other solution for this problem?


My trigger creates a new class for the callout which also have method runOnce which should contain the needed code to check for current account. Currently it returns true overtime.

My Trigger:

trigger SyncAccountToB2 on Account (after update, after insert, after delete, after undelete) {
    List<Account> tListNew = (Trigger.new != null) ? new List<Account>(Trigger.new) : null;
    List<Account> tListOld = (Trigger.old != null) ? new List<Account>(Trigger.old) : null;

    if (BeB2Callout2.runOnce(tListNew, tListOld) == true) {
        Map<Integer, Boolean> action = new Map<Integer, Boolean>();
        action.put(BeB2Callout2.A_UPDATE, Trigger.isUpdate);
        action.put(BeB2Callout2.A_INSERT, Trigger.isInsert);
        action.put(BeB2Callout2.A_DELETE, Trigger.isDelete);
        action.put(BeB2Callout2.A_UNDELETE, Trigger.isUndelete);

        Map<Id, SObject> omp;
        if (Trigger.isUpdate) {
            omp = new Map<Id, Sobject>(Trigger.old); 
        }
        else {
            omp = new Map<Id, Sobject>();
        }

        Organization co = [Select IsSandbox from Organization limit 1];

        if (co.IsSandbox || Test.isRunningTest()) {
            String s = '';
            if (Trigger.isUpdate) s = 'Update';
            if (Trigger.isInsert) s = 'Insert';
            if (Trigger.isDelete) s = 'Delete';
            if (Trigger.isUndelete) s = 'Undelete';
            System.Debug('Trigger: Sync Account to BeB2 backoffice: ' + s);
        }

        BeB2Callout2 b = new BeB2Callout2('Account', tListOld, tListNew, action, omp);
    }
}

And to check the accounts:

public static boolean runOnce(List<account> tListNew, List<account> tListOld) {
    Boolean isCurrentAccount = true;
    return isCurrentAccount;
}
1

Its because you are always returning true. You need to change your method and use a static global variable to maintain the state

public static boolean runflag;
public static boolean runOnce() {
    if(runflag)
       return false;
    else  {
       runflag = true;
       return true;
   }
}

and then call this method

if (BeB2Callout2.runOnce()) {
  // your code here
}
  • yep, I know, but problem is not to execute trigger just once, but to execute it only for the account edited by the user. – Obi_77 Oct 18 '17 at 8:24
  • @Obi_77 Then you might need to replace edit page with VF page. – Tushar Sharma Oct 18 '17 at 9:09
  • Simplest solution seems to be to compare current user Id with accounts system field LastModifiedById: Id currentUserId = UserInfo.getUserId(); if (a.LastModifiedById == currentUserId) {} – Obi_77 Oct 18 '17 at 13:06
  • @Obi_77 I don't think that will work because the record modified n trigger will also get same user in Last modified BY Id. – Tushar Sharma Oct 18 '17 at 13:08
1

You could use static boolean flags, as some people suggest, but you need to keep in mind the following points. (I would have posted a comment, but I don't have the reputation)

  • If FF (FinancialForce) has no triggers, you are in a safer position. If it does, Salesforce does NOT ensure the order of the trigger execution, which means you might end-up sending the Accounts updated by FF but not by you.
  • If you only plan to call your external system on updates that happens 1-by-1 (which I'll assume otherwise because you send list of accounts), you have to be careful if that list is BIGGER than 200 records, because Salesforce will break it into chunks and the static variables will not reset, which means that you will send the call only for the first 200 elements.

Take this post not as a solution but as a warning ;)

I hope it helps.

  • right, I noticed that the order of trigger execution is not assured, displayed account is not always the first one. – Obi_77 Oct 18 '17 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.