• Jacob Elliott 1
  • NEWBIE
  • 50 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 4
    Replies
Hi all, I'm a new Apex developer and I am trying to return a list in one method and reference it in another method. 

The bottom method "checkFieldChanges" is getting a list of fields that might have changed and I want to return that and reference it in the top method "resaveAccount" so that I can pass it to a batch class. Any help is greatly appreciated!

Top
public with sharing class CCIAllegianceAccountChanges {
    public static void resaveAccount(Account oldAcct, Account newAcct) {
        String acctType = newAcct.Account_Record_Type_Hidden__c;
        List <String> fieldChanged = new List<String>();
        boolean isACO = (oldAcct.V12C__Market__c == 'MHFN' || oldAcct.V12C__Market__c == 'PHQC') ? true : false;
        boolean isGroup = (acctType == 'Provider Group Account' || acctType == 'Ancillary Group Account') ? true : false;
        boolean isLocation = (acctType == 'Location' || acctType == 'Ancillary Location') ? true : false;

        if (isGroup && isACO) {

            if (fieldChanged.size() > 0) {
                //Query Locations
                try {
                    //Assigns the Parent ID to a variable for use in the query, queries for all locations, saves them in a list, and passes to batch class
                    String query = 'SELECT Id, Name, BillingStreet, BillingCity, BillingCountry, BillingState, BillingPostalCode, V12C__PR_Practice_Tax_ID_Number__c, Prac_TIN_Legal_Name__c, Child_Address_Override__c, Fee_Schedule__r.Name, Fee_Schedule_Effective_From_Date__c, V12C__PR_Practice_NPI_Number__c FROM Account WHERE Child_Address_Override__c = false AND (RecordType.DeveloperName = \'Location\' OR RecordType.Name = \'Ancillary Location\') AND ParentId =\'' + newAcct.Id + '\'';
                    List<Account> locations = Database.query(query);
                    System.debug('--------------List Size=' + locations.size());
                    Id batchInstanceId = Database.executeBatch(new CCIAllegianceLocationUpdates(locations, oldAcct, newAcct, String.join(fieldChanged, ',')), 100);

                    String queryCon = 'SELECT Id, Name, Allegiance_Status1__c, Last_Changed_Date__c, V12C__Effective_From_Date__c, V12C__Effective_Through_Date__c FROM Contact WHERE RecordType.DeveloperName = \'Provider\' AND Primary_Practicing_Location_Lookup__r.Child_Address_Override__c = false AND AccountId = \'' + newAcct.Id + '\'';
                    List<Contact> contacts = Database.query(queryCon);
                    System.debug('-------------- List Size=' + contacts.size());
                    Id batchInstanceIdCon = Database.executeBatch(new CCIAllegianceContactUpdates(contacts, oldAcct, newAcct, String.join(fieldChanged, ',')), 100);

                } catch (exception e) {
                    System.debug('Error Message: ' + e);
                }
            }
        } else if (isLocation && IsACO) {

            if (fieldChanged.size() > 0) {
                try {
                    String query = 'SELECT Id, Name, Last_Changed_Date__c, Allegiance_Status1__c, V12C__Effective_From_Date__c, V12C__Effective_Through_Date__c FROM Contact WHERE RecordType.DeveloperName = \'Provider\' AND Primary_Practicing_Location_Lookup__c = \'' + newAcct.Id + '\'';
                    List<Contact> contacts = Database.query(query);
                    System.debug('-------------- List Size=' + contacts.size());
                    Id batchInstanceId = Database.executeBatch(new CCIAllegianceContactUpdates(contacts, oldAcct, newAcct, String.join(fieldChanged, ',')), 100);

                    //CCIUpdateThisLocation.resaveLocation(oldAcct, newAcct, String.join(fieldChanged, ','));
                } catch (exception e) {
                    System.debug('Error Message: ' + e);
                }
            }
        }
    }

Bottom
public static List <String> checkFieldChanges(Account oldAcct, Account newAcct){
        List <String> fieldChanged = new List<String>();
        String acctType = newAcct.Account_Record_Type_Hidden__c;
        boolean isACO = (oldAcct.V12C__Market__c == 'MHFN' || oldAcct.V12C__Market__c == 'PHQC') ? true : false;
        boolean isGroup = (acctType == 'Provider Group Account' || acctType == 'Ancillary Group Account') ? true : false;
        boolean isLocation = (acctType == 'Location' || acctType == 'Ancillary Location') ? true : false;
        boolean billingChanged = (oldAcct.BillingStreet != newAcct.BillingStreet || oldAcct.BillingState != newAcct.BillingState || oldAcct.BillingCity != newAcct.BillingCity || oldAcct.BillingPostalCode != newAcct.BillingPostalCode || oldAcct.BillingCountry != newAcct.BillingCountry) ? true : false;
        boolean tinChanged = (oldAcct.PRAC_TIN_LEGAL_NAME__c != newAcct.PRAC_TIN_LEGAL_NAME__c || oldAcct.V12C__PR_Practice_Tax_ID_Number__c != newAcct.V12C__PR_Practice_Tax_ID_Number__c) ? true : false;
        boolean feeChanged = (oldAcct.Fee_Schedule__c != newAcct.Fee_Schedule__c) ? true : false;
        boolean NameChanged = (oldAcct.Name != newAcct.Name) ? true : false;

        if (billingChanged) {
            fieldChanged.add('Billing Address Changed');
        } else if (tinChanged) {
            fieldChanged.add('TIN Changed');
        }

        if(isLocation && isACO) {
         if (feeChanged) {
            fieldChanged.add('Fee Schedule Changed');
        } else if (nameChanged) {
            fieldChanged.add('Location Name Changed');
        }
        }

        return fieldChanged;
    }
}

 
I have a class that will update a field, Last_Changed_Date, on Contacts if certain fields on the Account are changed. This class worked but was touching so many records it timed out. My solution was to pass all the changes that needed to be made to Contact and pass a list to a Batch Method. Unfortunately, since adding the batch method it doesn't seem to be working. Any thoughts would be really appreciated!

Below is the main class
public with sharing class CCIProviderChangeAccountTracking {

    public static void resaveContact(Account oldAcct, Account newAcct) {

        if (oldAcct.Phone != newAcct.Phone ||
                oldAcct.ShippingAddress != newAcct.ShippingAddress ||
                oldAcct.V12C__PR_Practice_Tax_ID_Number__c != newAcct.V12C__PR_Practice_Tax_ID_Number__c ||
                oldAcct.BillingAddress != newAcct.BillingAddress) {
            system.debug('------Conditions Met!!!!!!!!!------');
            List<Contact> toSave = new List <Contact>();
            for (Contact con : [SELECT Id, Last_Changed_Date__c, AccountId FROM Contact WHERE AccountId = :newAcct.Id]) {
                //con.Last_Changed_Date__c = Datetime.NOW();
                toSave.add(con);
            }
            system.debug('jacob-------------' + toSave.size());

            try {
                Id batchInstanceId = Database.executeBatch(new CCIAllegianceUpdates(toSave), 200);
            } catch (exception e) {
                system.debug(e.getMessage());
            }
        }
    }
}

Here is the batch method that is being passed the list toSave.
 
global class CCIAllegianceUpdates implements Database.Batchable<sObject> {

    List<Contact> toSave = new List <Contact>();
    public CCIAllegianceUpdates(List<Contact> toSave) {
        toSave = toSave;
    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        system.debug('------Starting Batch!!!!!!!!!------');
        return null;
    }
    global void execute(Database.BatchableContext BC, List<Contact> scope) {
           
        
        update toSave;

    }
    global void finish(Database.BatchableContext BC) {
        system.debug('------Finish Batch!!!!!!!!!------');
    }

}

And finally this is where everything is being called
 
public void afterUpdate(SObject oldSo, SObject so) {
          Account oldAcct = (Account) oldSo;
          Account acct = (Account) so;
          CCIProviderChangeAccountTracking.resaveContact(oldAcct,acct);

    }

 
Hey everyone, I have created a trigger to update a field (Last_Changed_Date) on all related Contacts and I am getting the CPU Time out Limit error. I was hoping somoene could take a look and see if there is anyway to optimize?

trigger CCIAllegianceProvider on Account (before update) {

    //Map keeps track of accounts that have new addresses
    Map<Id, Account> changedProvider = new Map<Id, Account>();

    //Trigger.new is a list of Accounts that will be updated
    //The loop iterates over the list and adds accounts that have new addresses and adds to changedProvider list
    for (Integer i = 0; i < Trigger.new.size(); i++){

        if (   
        (Trigger.old[i].ShippingAddress != Trigger.new[i].ShippingAddress)

                || (Trigger.old[i].BillingAddress != Trigger.new[i].BillingAddress)
                
                || (Trigger.old[i].Phone != Trigger.new[i].Phone)

                || (Trigger.old[i].V12C__PR_Practice_Tax_ID_Number__c != Trigger.new[i].V12C__PR_Practice_Tax_ID_Number__c)

                )  {

            changedProvider.put(Trigger.old[i].id,

            Trigger.new[i]);
        }
    }



    List<Contact> updatedContacts = new List<Contact>();

    //Iterate over SOQL query and bind array with in
    for (Contact c :[SELECT Id, AccountId, Last_Changed_Date__c FROM Contact WHERE V12C__RecordType__c = 'Provider' AND V12C__Inactive__c = False AND AccountId IN :changedProvider.keySet()]){
        Account parentAccount = changedProvider.get(c.AccountId);
        c.Last_Changed_Date__c = Datetime.Now();
        updatedContacts.add(c);
    }

    update updatedContacts;
}
I created a trigger to update all related Contacts when an Account is updated. It was working perfectly and then I was asked to turn it into a regular class so that it can be called by an existing trigger...now it's not working. It looks like the code is being executed, but I'm not getting an error...Any thoughts?

Trigger that calls my class below (seems to be working fine):
/**
 * Class AccountHandler
 *
 * Trigger Handler for the Account SObject. This class implements the ITrigger
 * interface to help ensure the trigger code is bulkified and all in one place.
 */
public with sharing class CCIAccountHandler implements CCITriggerBase {

    // Constructor
    public CCIAccountHandler() {
    }

    public void bulkGeneral() {}
    /**
     * bulkBefore
     *
     * This method is called prior to execution of a BEFORE trigger. Use this to cache
     * any data required into maps prior execution of the trigger.
     */
    public void bulkBefore() {}

    public void bulkAfter() {}

    public void beforeInsert(SObject so) {}

    public void beforeUpdate(SObject oldSo, SObject so) {
        Account oldAcct = (Account) oldSo;
        Account acct = (Account) so;
        if(acct.V12C__Market__c != null && acct.V12C__Market__c.equals('MHFN')) {
            //SI-2: Send Email to the Account Owner and Quality Specialist
            CCISendEmail.sendDataIntegrationEmail(oldAcct, acct);
        }
        
    }

    /**
     * beforeDelete
     *
     * This method is called iteratively for each record to be deleted during a BEFORE
     * trigger.
     */
    public void beforeDelete(SObject so) {}

    public void afterInsert(SObject so) {
        Account acct = (Account) so;
    }

    public void afterUpdate(SObject oldSo, SObject so) {
    Account oldAcct = (Account) oldSo;
    Account acct = (Account) so;
    CCIProviderChangeAccountTracking.resaveContact(oldAcct,acct);

    }

    public void afterDelete(SObject so) {}

    /**
     * andFinally
     *
     * This method is called once all records have been processed by the trigger. Use this
     * method to accomplish any final operations such as creation or updates of other records.
     */
    public void andFinally() {}

}

My class that will run when certain fields on account is changed and will populate a datetime on contact called last changed:
public with sharing class CCIProviderChangeAccountTracking {

    public static void resaveContact(Account oldAcct, Account newAcct) {
         
        if (oldAcct.Phone != newAcct.Phone ||
                oldAcct.ShippingAddress != newAcct.ShippingAddress ||
                oldAcct.V12C__PR_Practice_Tax_ID_Number__c != newAcct.V12C__PR_Practice_Tax_ID_Number__c ||
                oldAcct.BillingAddress != newAcct.BillingAddress) {
            
            List<Contact> toSave = new List <Contact>();
            for (Contact con : [SELECT Id, Scorecard_Modified_Date__c FROM Contact WHERE Primary_Practicing_Location_Lookup__r.ParentId =:newAcct.Id]) {
                con.Last_Changed_Date__c = Datetime.NOW();
                toSave.add(con);    
            }
            system.debug('-------------' + toSave.size());
            
            try {
            update toSave;}
            catch(exception e){system.debug(e.getMessage());}
        }
    }
}

In the debug log I can see where it calls the class but isn't showing the system.debug
I am new to Apex and would really appreciate any help I can get! I have an Object called Interview and when a user creates an Interview Task with a record type of Interview, I want a new Interview Record to be created. When trying to save the new interview record, I get this error: "execution of AfterInsert caused by: System.SObjectException: DML statement cannot operate on trigger.new or trigger.old ():. 

Below is my Code
 
trigger CreateInterview on Task (after insert) {
    for (Task t : Trigger.new) {
        Interview__c i                          = new Interview__c();
        i.CreatedById                          = t.OwnerId;
        i.Candidate__c                        = t.Candidate__c;
        i.Interview_Date__c                = t.ActivityDate;
        i.Job_Position_Text__c           = t.Job_Position__c;
        i.Hiring_Manager__c               = t.Hiring_Manager__c;
        i.Hiring_Location__c                = t.Hiring_Location__c;
        i.Hiring_Unit_Department__c  =  t.Hiring_Unit_Department__c;
        i.Id                                            = t.Interview__c;
        i.Comments__c                        = t.Description;
        i.Name                                     = t.Subject;
        i.Id                                            = t.WhatId;
        insert t;
    }
}

User-added imageUser-added image
Hello all, I'm extremely new to Apex, so please bear with me and forgive me for any confusion. :-) 

I have a custom object calledProject API: MPM4_BASE__Milestone1_Project__c (I know, packaged content). When a user creates a new project with the record type OKR, a field in the new project window, called Record Type, is set to OKR. There is another field, which is text/input, called Project name. After a User clicks new project and selects OKR as the record type, I want to set Project Name equal to either the record type=OKR, or the field Record Type, which will also be OKR. The end goal is to pre-populate the field Project Name with the value OKR. 

Here is what I've tried so far, but nothing pre-populates and I get the error "OKR_Project_Trigger: execution of BeforeInsert caused by: System.StringException: Invalid id: OKR ()"

Any help would be greatly appreciated!
 
Trigger OKR_Project_Trigger on MPM4_BASE__Milestone1_Project__c (before insert, before update) {

    for (MPM4_BASE__Milestone1_Project__c project: Trigger.new) {
    
        if (project.RecordTypeId == 'OKR') {
        
            project.Name = project.RecordTypeId;
        }    
    }
}
I have a class that will update a field, Last_Changed_Date, on Contacts if certain fields on the Account are changed. This class worked but was touching so many records it timed out. My solution was to pass all the changes that needed to be made to Contact and pass a list to a Batch Method. Unfortunately, since adding the batch method it doesn't seem to be working. Any thoughts would be really appreciated!

Below is the main class
public with sharing class CCIProviderChangeAccountTracking {

    public static void resaveContact(Account oldAcct, Account newAcct) {

        if (oldAcct.Phone != newAcct.Phone ||
                oldAcct.ShippingAddress != newAcct.ShippingAddress ||
                oldAcct.V12C__PR_Practice_Tax_ID_Number__c != newAcct.V12C__PR_Practice_Tax_ID_Number__c ||
                oldAcct.BillingAddress != newAcct.BillingAddress) {
            system.debug('------Conditions Met!!!!!!!!!------');
            List<Contact> toSave = new List <Contact>();
            for (Contact con : [SELECT Id, Last_Changed_Date__c, AccountId FROM Contact WHERE AccountId = :newAcct.Id]) {
                //con.Last_Changed_Date__c = Datetime.NOW();
                toSave.add(con);
            }
            system.debug('jacob-------------' + toSave.size());

            try {
                Id batchInstanceId = Database.executeBatch(new CCIAllegianceUpdates(toSave), 200);
            } catch (exception e) {
                system.debug(e.getMessage());
            }
        }
    }
}

Here is the batch method that is being passed the list toSave.
 
global class CCIAllegianceUpdates implements Database.Batchable<sObject> {

    List<Contact> toSave = new List <Contact>();
    public CCIAllegianceUpdates(List<Contact> toSave) {
        toSave = toSave;
    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        system.debug('------Starting Batch!!!!!!!!!------');
        return null;
    }
    global void execute(Database.BatchableContext BC, List<Contact> scope) {
           
        
        update toSave;

    }
    global void finish(Database.BatchableContext BC) {
        system.debug('------Finish Batch!!!!!!!!!------');
    }

}

And finally this is where everything is being called
 
public void afterUpdate(SObject oldSo, SObject so) {
          Account oldAcct = (Account) oldSo;
          Account acct = (Account) so;
          CCIProviderChangeAccountTracking.resaveContact(oldAcct,acct);

    }

 
Hey everyone, I have created a trigger to update a field (Last_Changed_Date) on all related Contacts and I am getting the CPU Time out Limit error. I was hoping somoene could take a look and see if there is anyway to optimize?

trigger CCIAllegianceProvider on Account (before update) {

    //Map keeps track of accounts that have new addresses
    Map<Id, Account> changedProvider = new Map<Id, Account>();

    //Trigger.new is a list of Accounts that will be updated
    //The loop iterates over the list and adds accounts that have new addresses and adds to changedProvider list
    for (Integer i = 0; i < Trigger.new.size(); i++){

        if (   
        (Trigger.old[i].ShippingAddress != Trigger.new[i].ShippingAddress)

                || (Trigger.old[i].BillingAddress != Trigger.new[i].BillingAddress)
                
                || (Trigger.old[i].Phone != Trigger.new[i].Phone)

                || (Trigger.old[i].V12C__PR_Practice_Tax_ID_Number__c != Trigger.new[i].V12C__PR_Practice_Tax_ID_Number__c)

                )  {

            changedProvider.put(Trigger.old[i].id,

            Trigger.new[i]);
        }
    }



    List<Contact> updatedContacts = new List<Contact>();

    //Iterate over SOQL query and bind array with in
    for (Contact c :[SELECT Id, AccountId, Last_Changed_Date__c FROM Contact WHERE V12C__RecordType__c = 'Provider' AND V12C__Inactive__c = False AND AccountId IN :changedProvider.keySet()]){
        Account parentAccount = changedProvider.get(c.AccountId);
        c.Last_Changed_Date__c = Datetime.Now();
        updatedContacts.add(c);
    }

    update updatedContacts;
}
Hello all, I'm extremely new to Apex, so please bear with me and forgive me for any confusion. :-) 

I have a custom object calledProject API: MPM4_BASE__Milestone1_Project__c (I know, packaged content). When a user creates a new project with the record type OKR, a field in the new project window, called Record Type, is set to OKR. There is another field, which is text/input, called Project name. After a User clicks new project and selects OKR as the record type, I want to set Project Name equal to either the record type=OKR, or the field Record Type, which will also be OKR. The end goal is to pre-populate the field Project Name with the value OKR. 

Here is what I've tried so far, but nothing pre-populates and I get the error "OKR_Project_Trigger: execution of BeforeInsert caused by: System.StringException: Invalid id: OKR ()"

Any help would be greatly appreciated!
 
Trigger OKR_Project_Trigger on MPM4_BASE__Milestone1_Project__c (before insert, before update) {

    for (MPM4_BASE__Milestone1_Project__c project: Trigger.new) {
    
        if (project.RecordTypeId == 'OKR') {
        
            project.Name = project.RecordTypeId;
        }    
    }
}