0

I have a trigger that runs when the status of a contract record is set to a specific value. Within my trigger, I need to have a specific field value from the triggering record available to be assigned to a variable so I can reference it later.

I did some searching and found some information about using a public static string, but i'm struggling to the assign the value so I can use it elsewhere.

In the code below, I need the value of the ia_crm__Contract_ID__c field from triggering record to be stored in "intacctContractId".

public class IntacctContractRevHandler {
    
    private integer pageSize = 10000;
    private string obj = '';
    private List<String> fields = new List<String> ();
    private string query = '';
    IntacctClient client = null;
    Map<String, String> ContractRevScheduleMap = new Map<String, String> ();
    Map<String, Intacct_Revenue_Recognition_Schedule__c> revRecMap = new Map<String, Intacct_Revenue_Recognition_Schedule__c> (); 
    Map<string,string> dataMap = new Map<string,string>(); 
    
    private List<Intacct_Revenue_Recognition_Schedule__c> revSchedsToCreate;
    private List<Intacct_Revenue_Recognition_Schedule__c> revSchedsToUpdate;
    private List<Intacct_Revenue_Recognition_Schedule__c> revRecsToDelete;
    private Set<String> recNumsFromIntaact = new Set<String> ();
    
    private ia_crm__Sales_Order__c defaultOrder = null;
    private static boolean hasExecuted = false;
    integer code;
    
    private string oppId;
    private string intacctContractId;
    
@AuraEnabled
    public static string getContractIdbyRecordId(id currentRecordID) {
        List<ia_crm__Intacct_Contract__c> contracts = [SELECT ia_crm__Contract_ID__c FROM ia_crm__Intacct_Contract__c WHERE id = :currentRecordID LIMIT 1];
        String intacctContractId = '';
        return (!contracts.isEmpty()) ? contracts[0].ia_crm__Contract_ID__c: '';      
        } 

When I run the debug, my intacctContractId string remains Null. What am I missing/doing wrong here?

Here is the trigger that calls this specific Apex Class:

public class IntacctContractTriggerHandler  {
public static IntacctContractTriggerHandler getHandler()
  {
    return new IntacctContractTriggerHandler();
  }


  public void ExecuteHandler(Map<Id, ia_crm__Intacct_Contract__c> oldRecords, List<ia_crm__Intacct_Contract__c> updatedRecords)
  {
         if(ValidateRunningUser.ShouldTriggerAbort())
            return;
        
    Map<string, id> nameIdMap = new Map<string, id> ();
    for (ia_crm__Intacct_Contract__c record : updatedRecords)
    {
            System.debug('Record');
            System.debug(record);
      if (oldRecords.get(record.id).Intaact_Integration_Status__c != 'Ready to Sync' &&
          record.Intaact_Integration_Status__c == 'Ready to Sync')
      {
        nameIdMap.put(record.Name, record.Id);

      }
    }

    if (nameIdMap.size() > 0)
    {
      ExecuteCallout(nameIdMap);
    }
  }

  @Future(callout=true)
  public static void ExecuteCallout(Map<String, Id> recordMap)
  {
    try
    {
      for (string name : recordMap.keySet())
      {
          string rId = recordMap.get(name);
        IntacctContractRevHandler handler = new IntacctContractRevHandler();

        System.debug('rid ' + rid + ' ' + name);
        handler.QueryRevRecSchedules(name, rId,1);

        ia_crm__Intacct_Contract__c record = [Select id, Intaact_Integration_Status__c from ia_crm__Intacct_Contract__c
                                         where id = :rId];

        record.Intaact_Integration_Status__c = 'In Sync';

        update record;
      }


    }
    catch(Exception e)
    {

    }
  }
}

And if needed, here's the full code for my class:

public class IntacctContractRevHandler {
    
    private integer pageSize = 10000;
    private string obj = '';
    private List<String> fields = new List<String> ();
    private string query = '';
    IntacctClient client = null;
    Map<String, String> ContractRevScheduleMap = new Map<String, String> ();
    Map<String, Intacct_Revenue_Recognition_Schedule__c> revRecMap = new Map<String, Intacct_Revenue_Recognition_Schedule__c> (); 
    Map<string,string> dataMap = new Map<string,string>(); 
    
    private List<Intacct_Revenue_Recognition_Schedule__c> revSchedsToCreate;
    private List<Intacct_Revenue_Recognition_Schedule__c> revSchedsToUpdate;
    private List<Intacct_Revenue_Recognition_Schedule__c> revRecsToDelete;
    private Set<String> recNumsFromIntaact = new Set<String> ();
    
    private ia_crm__Sales_Order__c defaultOrder = null;
    private static boolean hasExecuted = false;
    integer code;
    
    private string oppId;
    private string intacctContractId;
    
    @AuraEnabled
    public static string getContractIdbyRecordId(id currentRecordID) {
        List<ia_crm__Intacct_Contract__c> contracts = [SELECT ia_crm__Contract_ID__c FROM ia_crm__Intacct_Contract__c WHERE id = :currentRecordID LIMIT 1];
        String intacctContractId = '';
        return (!contracts.isEmpty()) ? contracts[0].ia_crm__Contract_ID__c: '';      
        } 
  
    public IntacctContractRevHandler ()
    {
        client = new IntacctClient();
        defaultOrder = [Select id from ia_crm__Sales_Order__c where name = :client.getConfig().DefaultSalesOrder];
        //intacctContractId = [Select id, ia_crm__Contract_ID__c from ia_crm__Intacct_Contract__c where IContracts.id = OppId LIMIT 1];
        revSchedsToCreate = new List<Intacct_Revenue_Recognition_Schedule__c> ();
        revSchedsToUpdate = new List<Intacct_Revenue_Recognition_Schedule__c> ();
            System.debug('$$$$$$$$$$$$$$$$$$$$$$$$$$$$'); 
            System.debug('OppId ' + oppId);
            System.debug('IntacctContractId ' + intacctContractId );  
    }
            
    
    public void GetAPISession()
    {
        
        SessionIdFunction apiSession = new SessionIdFunction();
        client.execute(apiSession, new RequestConfig());
        Reset();
        
    }
    
    private void QueryExistingRevRecs(integer c)
    {
        if(hasExecuted)
            return;
        this.code = c;
        List<Intacct_Revenue_Recognition_Schedule__c> existingSchedules = null;
        string query = 'Select Id,Amount__c, '
            + 'Quantity__c,RECORDNO__c,Intacct_Contract__c, '
            + 'Posting_Date__c,Source_Identifier__c,Sales_Order_ID__c '
            + 'From Intacct_Revenue_Recognition_Schedule__c where ';
        if (code == 0)
        {
            query = query + 'Sales_Order_ID__c=' + '\'' + oppId + '\'';
        }
        else {
            query = query + 'Intacct_Contract__c= ' + '\'' + oppId + '\'';
        }
        
        query = query + ' and Source_Identifier__c != \'Salesforce\'';
        
        List<Intacct_Revenue_Recognition_Schedule__c> existing = Database.query(query);
        
        if (existing != null && existing.size() > 0)
        {
            for (Intacct_Revenue_Recognition_Schedule__c r : existing)
            {
                revRecMap.put(String.valueOf(r.RECORDNO__c), r);
            }
        }
    }

     public void QueryRevRecSchedulesByActivationRecord(string name, string oppID, integer t)
    {
        System.debug('%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
        System.debug('Starting QueryRevRecSchedules');
        code = t;
        this.oppId = oppId;
        QueryExistingRevRecs(t);
       
        GetContractRevenueSchedulesAndLineNumbers();
        Reset();
        try
        {
            GetContractRevenueScheduleById(name);
            ValidateAndDeleteRevRecsNotInIntaact(recNumsFromIntaact);
            
        }
        catch(Exception e)
        {
            System.debug(e.getMessage());
            System.debug(e.getLineNumber());
            System.debug(e.getStackTraceString());
        }
        hasExecuted = true;
        System.debug('RevRec Size to create ' + revSchedsToCreate.size());
        if (revSchedsToCreate.size() > 0)
        {
            System.debug(revSchedsToCreate);
            insert revSchedsToCreate;
        }
        
        
        if (revSchedsToUpdate.size() > 0)
        {
            System.debug('Rev rec to update ');
            System.debug(revSchedsToUpdate);
            update revSchedsToUpdate;
        }
        
        if (revRecsToDelete.size() > 0)
        {
            System.debug('Rev rec to delete ');
            System.debug(revRecsToDelete);
            delete revRecsToDelete;
        }
    }
    
    public boolean QueryRevRecSchedules(string name, string oppID, integer t)
    {
       boolean status = true;
       boolean recordUpdate = true;
       boolean recordCreate = true;
        System.debug('%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
        System.debug('Starting QueryRevRecSchedules');
        code = t;
        this.oppId = oppId;

        
        System.debug('!!!!!!!!!!!!!!!!!!!!!!!!!!!');
        System.debug('OppId ' + oppId);
        System.debug('IntacctContractId ' + IntacctContractId);        
        QueryExistingRevRecs(t);
        
        GetContractRevenueSchedulesAndLineNumbers(); 
        Reset();
        try
        {
            GetRevenueContracts(name);
            ValidateAndDeleteRevRecsNotInIntaact(recNumsFromIntaact);
            
        }
        catch(Exception e)
        {
            System.debug(e.getMessage());
            System.debug(e.getLineNumber());
            System.debug(e.getStackTraceString());
        }
        hasExecuted = true;
        System.debug('RevRec Size to create ' + revSchedsToCreate.size());
        if (revSchedsToCreate.size() > 0)
        {
            System.debug(revSchedsToCreate);
            insert revSchedsToCreate;
        }
        else{
          recordCreate = false;
        }
        
        
        if (revSchedsToUpdate.size() > 0)
        {
            System.debug('Rev rec to update ');
            System.debug(revSchedsToUpdate);
            update revSchedsToUpdate;
        }
        else{
          recordUpdate = false;

        }
        
        if (revRecsToDelete.size() > 0)
        {
            System.debug('Rev rec to delete ');
            System.debug(revRecsToDelete);
            delete revRecsToDelete;
        }

        if(recordCreate == false && recordCreate == false)
        {
           status = false;
        }

        return status;
    }

      
    public void GetRevenueContracts(string name)
    {
        
        string field = 'NAME';
        AddField('CONTRACTID');
        AddField('NAME');
        
        query = field + ' = \'' + name + '\'';
        
        obj = 'CONTRACT';
        
        
        //  readRequest.setDocParId('Revenue Activation');
        
        OnlineResponse resp = ExecuteReadByQuery(field);
        System.debug(resp);
        Reset();
        GetContractRevenueSchedules(resp);
    }
    
    private OnlineResponse ExecuteReadByQuery(string field)
    {
        QueryString requestQuery = new QueryString(query);
        
        ReadByQuery readRequest = new ReadByQuery();
        readRequest.setObjectName(obj);
        readRequest.setFields(fields);
        readRequest.setQuery(requestQuery);
        readRequest.setPageSize(pageSize);
        
        return client.execute(readRequest, new RequestConfig());
    }

    private void GetContractRevenueScheduleById(string revRecId)
    {
        
        
        AddField('RECORDNO');
        AddField('LINENO');
        
        
        obj = 'CONTRACTREVENUESCHEDULE';
        integer counter = 0;
     
        query = 'CONTRACTID' + ' = \'' + revRecId + '\'';
        OnlineResponse revSchedule = ExecuteReadByQuery('');
        
        System.debug('revSchedule ' + revSchedule);
        Reset();
        GetContractRevenueScheduleEntries(revSchedule);
        Reset();
    }

    public void GetContractRevenueSchedules(OnlineResponse resp)
    {
        
        
        AddField('RECORDNO');
        AddField('LINENO');
        
        
        obj = 'CONTRACTREVENUESCHEDULE';
        boolean isContractIdSet = false;
        integer counter = 0;
        query = 'CONTRACTID' + ' = \'';
        for (Result nodes : resp.results)
        {
            
            string CONTRACTID = '';
            
            for (dom.XmlNode res : nodes.getData())
            {
                if (res.getName() == 'CONTRACT')
                {
                    for (dom.XmlNode r : res.getChildElements())
                    {
                        if (r.getName() == 'CONTRACTID')
                        {
                            CONTRACTID = r.getText();
                            intacctContractId = CONTRACTID;
                            System.debug('88888888888888888888888888888888' );  
                            System.debug('intacctContractId ' + intacctContractId );  
                            System.debug('88888888888888888888888888888888' );  
                            isContractIdSet = true;
                            obj = 'CONTRACTREVENUESCHEDULE';
                            
                            if(counter == 0)
                            {
                                query = 'CONTRACTID' + ' = \'' + CONTRACTID + '\'';
                                
                            }
                            else
                            {
                                query =  query +' OR ' +'CONTRACTID' + ' = \''  + CONTRACTID+ '\'';
                            }
                            
                            counter++;

                            {
                                
                                System.debug('#############################');
                                System.debug('#GetRevenueScheduleEntries###');
                                System.debug('ContractId ' + CONTRACTID);                                                                                          
                                System.debug('#############################');
                                
                                
                            }
                            
                        }
                    }
                }
            }
            
            
        }
        
        OnlineResponse revSchedule = ExecuteReadByQuery('');
        
        System.debug('revSchedule ' + revSchedule);
        Reset();
        GetContractRevenueScheduleEntries(revSchedule);
        Reset();
    }
    
////////////////////////////////////////////////////////////////////////    
    public void GetContractRevenueSchedulesAndLineNumbers()
    {
        AddField('CONTRACTID');
        AddField('RECORDNO');
        AddField('LINENO');
        query = 'CONTRACTID' + ' = \'' + IntacctContractId + '\'';
              
        obj = 'CONTRACTREVENUESCHEDULE';
             
        OnlineResponse resp = ExecuteReadByQuery('');
        
        for (dom.XmlNode n : resp.results[0].getData())
        {
            dom.XmlNode ContractIDNode = n.getChildElement('CONTRACTID', null); 
            dom.XmlNode RecordNoNode = n.getChildElement('RECORDNO', null);           
            dom.XmlNode LineNoNode = n.getChildElement('LINENO', null);
            
            System.debug('CONTRACTREVENUESCHEDULE CONTRACTID ' + ContractIDNode.getText());
            System.debug('CONTRACTREVENUESCHEDULE RECORDNO ' + RecordNoNode.getText());
            System.debug('CONTRACTREVENUESCHEDULE LINENO ' + LineNoNode.getText());
            ContractRevScheduleMap.put(RecordNoNode.getText(), LineNoNode.getText());
        }
        System.debug(ContractRevScheduleMap);
    }   
////////////////////////////////////////////////////////////////////////    
  
    public void GetContractRevenueScheduleEntries(OnlineResponse resp)
    {
        AddField('*');
        
        
        obj = 'CONTRACTREVENUESCHEDULEENTRY';
        boolean isContractIdSet = false;
        
        Result nodes = resp.results[0];
        integer counter = 0;
        string recordNo = '';
        query = 'SCHEDULEKEY' + ' = \'';
        boolean executeQuery = false;
        if (nodes.getData() == null)
            return;
        for (dom.XmlNode res : nodes.getData())
        {
            System.debug('nodes ');
            
            if (res.getName() == 'CONTRACTREVENUESCHEDULE')
            {
                for (dom.XmlNode r : res.getChildElements())
                {
                    if (r.getName() == 'RECORDNO')
                    {
                        executeQuery = true;
                        recordNo = r.getText();
                        isContractIdSet = true;
                        
                        if(counter == 0)
                        {
                            query = 'SCHEDULEKEY' + ' = \'' + recordNo + '\'';
                        }
                        else
                        {
                            query = query + ' OR '+'SCHEDULEKEY' + ' = \'' + recordNo + '\'';
                            
                        }
                        counter++;
                        
                    }
                }
            }
        }
        
        System.debug('#############################');
        System.debug('#############################');
        
        System.debug('#############################');
        if(executeQuery)
        {
            OnlineResponse revSchedule = ExecuteReadByQuery('');
            CreateRevRecSched(revSchedule, RECORDNO);
            System.debug('revSchedule ' + revSchedule);
        }
        
    }
    
    private void CreateRevRecSched(OnlineResponse resp, String RECORDNO)
    {
        System.debug('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
        System.debug('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
        
        System.debug('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
        System.debug(resp.results[0].getData());
        for (Dom.XMLNode revRec : resp.results[0].getData())
        {
            
            Intacct_Revenue_Recognition_Schedule__c sched = null;
            System.debug('Rec sched entry');
            System.debug(revRec);
            string LineNum = revRec.getChildElement('SCHEDULEKEY', null).getText();
            
            string linenumber = '';
                       
            if (String.isNotBlank(LineNum))
            {
                if (this.ContractRevScheduleMap.containsKey(LineNum))
                    linenumber = this.ContractRevScheduleMap.get(LineNum);
            }
            
            string recordNumber = revRec.getChildElement('RECORDNO', null).getText();
            recNumsFromIntaact.add(recordNumber);
            decimal amount = 0.0;
            amount = Decimal.valueOf(revRec.getChildElement('AMOUNT', null).getText());
           
            System.debug('Amount ' + amount);
            string dt = revRec.getChildElement('POSTINGDATE', null).getText().replace('/', '-');
            string line = revRec.getChildElement('RECORDNO', null).getText() + '--' + linenumber;
            decimal recNum = Decimal.valueOf(revRec.getChildElement('RECORDNO', null).getText());
            string source = revRec.getChildElement('SCHEDULEKEY', null).getText();
            
            boolean isCreate = false;
            
            System.debug('recordNumber  '+ recordNumber);           
            System.debug('linenumber '+ linenumber); 
            System.debug('LineNum '+ LineNum);                             
            System.debug(revRecMap);
            if (!revRecMap.containsKey(recordNumber))
            {
                sched = new Intacct_Revenue_Recognition_Schedule__c();
                isCreate = true;
                
            }
            else {
                sched = revRecMap.get(recordNumber);
            }
            
            
            sched.Amount__c = amount;
            sched.Intacct_Contract_line_no__c = line;
            sched.Quantity__c = 1;
            sched.RECORDNO__c = recNum;            
            sched.Posting_Date__c = setStringToDateFormat(dt);
            sched.Source_Transaction__c = source;
            
            if (isCreate)
            {
                if (code == 0)
                {
                    sched.Sales_Order_ID__c = oppId;
                }
                else {
                    sched.Intacct_Contract__c = oppId;
                    sched.Sales_Order_ID__c = defaultOrder.Id;
                }
                
                System.debug('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^');
                System.debug('Adding');
                System.debug(revSchedsToCreate);
                revSchedsToCreate.add(sched);
                
            }
            else {
                revSchedsToUpdate.add(sched);
            }
            
            System.debug('IsUpdate : ' + isCreate);
            System.debug('rev rec ' + sched);
            
        }
        
    }
    
    private void ValidateAndDeleteRevRecsNotInIntaact(Set<String> currentRevRecs)
    {
        System.debug('))))))))))))))))))))))))))))))))))))))))))))))');//ValidateAndDeleteRevRecsNotInIntaact
        System.debug('ValidateAndDeleteRevRecsNotInIntaact');
        System.debug('))))))))))))))))))))))))))))))))))))))))))))))');
        revRecsToDelete =
            new List<Intacct_Revenue_Recognition_Schedule__c> ();
        
        System.debug(currentRevRecs);
        for (string key : revRecMap.keySet())
        {
            System.debug('key ' + key);
            if (!currentRevRecs.contains(key))
            {
                System.debug('deleting ' + key);
                revRecsToDelete.add(revRecMap.get(key));
            }
        }   
    }
    
    private Date setStringToDateFormat(String myDate) {
        String[] myDateOnly = myDate.split(' ');
        String[] strDate = myDateOnly[0].split('-');
        Integer myIntDate = integer.valueOf(strDate[1]);
        Integer myIntMonth = integer.valueOf(strDate[0]);
        Integer myIntYear = integer.valueOf(strDate[2]);
        Date d = Date.newInstance(myIntYear, myIntMonth, myIntDate);
        return d;
    }
    
    private void AddField(string field)
    {
        fields.add(field);
    }
    
    private void Reset()
    {
        fields.clear();
    }

}
2
  • Hi there, in your question you've mentioned a trigger, would you be able to include that for context on where you are calling this subsequent class? Also, is there any additional logic within this class? Commented Jan 12, 2023 at 21:10
  • @CallumMacErlich Just updated my original post with the extra information Commented Jan 12, 2023 at 21:20

1 Answer 1

1

The easiest way to do achieve what you need is to move away from passing Record Ids to your subsequent methods, but pass the entire record that the trigger is handling. This means you have access to the entire record (including all the fields) and don't need to make additional SOQL queries to retrieve the records again.

Looking at your code, you should also store all of your updated records in a List, and then update all the records at once. Currently the executeCallout method is updating individual records inside a for loop which will fail if a large number of records are updated at the same time.

Without re-writing the entire class, we can set the static variable from within the ExecuteCallout method as shown below:

@Future(callout=true)
public static void ExecuteCallout(Map<String, Id> recordMap){
    try {
        
        //Create a map of Record Id to Contract Id to save querying in loop.
        Map<Id,String> idContractIdMap = new Map<Id,String>();
        List<ia_crm__Intacct_Contract__c> recordList = [SELECT Id, ia_crm__Contract_ID__c FROM ia_crm__Intacct_Contract__c WHERE Id IN : recordMap.values()];
        for(ia_crm__Intacct_Contract__c contract : recordList){
            idContractIdMap.put(contract.Id, contract.ia_crm__Contract_ID__c);
        }

        //Create list of updated contracts so that we don't do DML operations in loop
        List<ia_crm__Intacct_Contract__c> updatedRecordList = new List<ia_crm__Intacct_Contract__c>();
        for (string name : recordMap.keySet()){
            string rId = recordMap.get(name);
            IntacctContractRevHandler handler = new IntacctContractRevHandler();
            handler.intacctContractId = idContractIdMap.get(rId);

            System.debug('rid ' + rid + ' ' + name);
            handler.QueryRevRecSchedules(name, rId,1);

            ia_crm__Intacct_Contract__c record = [Select id, Intaact_Integration_Status__c from ia_crm__Intacct_Contract__c
                                        where id = :rId];

                record.Intaact_Integration_Status__c = 'In Sync';

            updatedRecordList.add(record);
        }

        //Update all updated contract records
        update updatedRecordList;
    }
    catch(Exception e)
    {

    }
}

I've moved the update outside of the loop as well as doing a single query to reduce the chance of this hitting limits.

9
  • Sounds easier said than done unfortunately. I'm not a developer and am only modifying existing code to expand on its functionality, so my knowledge on the subject is beyond limited. Short of rewriting the code at this point, is there a simple way to get the record id into my variable so the rest of the trigger does what I need? Commented Jan 12, 2023 at 21:34
  • I would recommend that this is re-written based on what I've seen. However I'll post another answer that will let you solve the issue. Commented Jan 12, 2023 at 21:41
  • First - THANK YOU for helping me with this! I dropped in what you provided, but i'm getting a "Compile Error: Variable does not exist: ia_crm__Intacct_Contract__c" error.. on line 9 of the code you wrote (idContractIdMap.put) Commented Jan 12, 2023 at 22:28
  • Sorry! I had a spelling mistake (contact vs contract). I've updated that now so hopefully that is fixed. Commented Jan 12, 2023 at 23:11
  • Still getting an error. Not sure if it's related, but i first get an error about "Compile Error: Missing ';' at 'for' " and when i add a ; after the Select statement, is when i get the "Compile Error: Variable does not exist: ia_crm__Intacct_Contract__c" error Commented Jan 12, 2023 at 23:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .