[SalesForce] System.DmlException: Insert failed. first error: REQUIRED_FIELD_MISSING, Required fields are missing: [AccountID__c]: [AccountID__c] line 49

I'm trying to CREATE or UPDATE an SOBJECT "AccountProjectEngament__c"

this following code works on my sandbox, but i can't upload it to my production site.

i have the following error:

Test_CommitteeMember.myUnitTest(), Details: System.DmlException:
Insert failed. First exception on row 0; first error:
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AccountEngagementTrigger:
execution of AfterInsert caused by: System.DmlException: Insert
failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING,
Required fields are missing: [AccountID__c]: [AccountID__c]
Class.AccountEngagement.allAccountEngagementRecordList: line 49,
column 1 Trigger.AccountEngagementTrigger: line 5, column 1: []
Class.Test_CommitteeMember.myUnitTest: line 84, column 1

which think i missing the accountID Field.

But as i said it is working on my sandbox, and i have to field missing.

here is my class:

public class AccountEngagement {

    public static void allAccountEngagementRecordList(MN4__Committee_Member__c[] Committee_Member){

        if(Committee_Member[0].MN4__Active__c==true)
        {
            ID committeeID   = Committee_Member[0].MN4__Committee__c;
            ID contactID     = Committee_Member[0].MN4__Contact__c;
            ID accountID     = Committee_Member[0].MN4__Contact__r.Account.Id;

            AggregateResult[] AvgEngagementofAccountInCommittee = [SELECT AVG(Engagement_Quality__r.Engagement_Level__c)avg FROM MN4__Committee_Member__c WHERE MN4__Active__c = True AND MN4__Committee__c =:committeeID AND MN4__Contact__r.Account.Id = :accountID];        

            decimal engagementQualityLevel;
            for(AggregateResult b : AvgEngagementofAccountInCommittee)
            {       
                engagementQualityLevel = (decimal)b.get('avg');
            }

            List<AccountProjectEngament__c> accountProjectEngamentList = new List<AccountProjectEngament__c>();

            accountProjectEngamentList = [SELECT Max_Engamment__c, Project_Engagement__c FROM AccountProjectEngament__c WHERE Committee__c = :committeeID and AccountID__c = :accountId];
            delete accountProjectEngamentList;

            AggregateResult[] MaxEngagementByAccountAndProject = [SELECT Max(Engagement_Quality__r.Engagement_Level__c)max FROM MN4__Committee_Member__c WHERE MN4__Active__c = True AND MN4__Committee__c =:committeeID AND MN4__Contact__r.Account.Id = :accountID];

            string MaxEngagement;
            for(AggregateResult c : MaxEngagementByAccountAndProject)
            {       

                if((Decimal)c.get('max') == 100)
                {
                    MaxEngagement = 'Lead';
                }else if((Decimal)c.get('max') == 5)
                {
                    MaxEngagement = 'Dormant';
                }else if((Decimal)c.get('max') == 50)
                {
                    MaxEngagement = 'Active';
                }else if((Decimal)c.get('max') == 10)
                {
                    MaxEngagement = 'Passive';
                }else
                {
                    MaxEngagement = 'Undefined';
                }
            } 

            AccountProjectEngament__c NewAccountProjectEngament = new AccountProjectEngament__c(AccountID__c = accountID, Project_Engagement__c = engagementQualityLevel, Max_Engamment__c = MaxEngagement, Committee__c = committeeID);
            insert NewAccountProjectEngament;
        }
    }
}

And my Trigger:

trigger AccountEngagementTrigger on MN4__Committee_Member__c (after delete, before insert, before update) {
if (trigger.isInsert || trigger.isUpdate)
{
    MN4__Committee_Member__c[] Committee_Member = Trigger.new;
    AccountEngagement.allAccountEngagementRecordList(Committee_Member);
}else if(trigger.isDelete)
{
MN4__Committee_Member__c[] Committee_Member  = Trigger.old;
AccountEngagement.allAccountEngagementRecordList(Committee_Member);
}
}

Best Answer

In triggers, only the immediate fields of the SObject are populated. So this code will not work:

ID accountID = Committee_Member[0].MN4__Contact__r.Account.Id;

as it is referencing the related Contact object and then in turn the Contact's Account object. Instead you will need to add a query that uses the Committee_Member[0].MN4__Contact__c ID field to query the related Contact object for the Contact.AccountId field.

Also your trigger is coded assuming there is only ever one MN4__Committee_Member__c object inserted/updated/deleted and will not produce correct results when more than one of those objects is inserted/updated/deleted. So you should also apply some of the bulkification patterns in Apex Code Best Practices to address this.

Related Topic