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
Peter CowenPeter Cowen 

Trigger failing on live but works on sandbox

I have deployed a trigger to live but it seems to not populate the service Contract but in sandbox it does.
The name of the fields are the same. The trigger is
I have tested the below on our test system and it works correctly. The fields are the same in Live and Sandbox but the trigger will not populate the service contract field on a case.
I have tried removing the recordtype, using specific account but no luck on Live.
trigger UpdateServiceContract on Case (before insert,before update, after update) {
if (trigger.isBefore && trigger.isInsert) {
for (Case c : trigger.new) {
if (c.RecordTypeID == '012D0000000NWyPIAW')
if (c.service_contract__c == NULL){
try{
//c.Service_Contract__c = [select Id from ServiceContract where AccountId ='810D0000000Cfza' and Primary_Service_Contract__c = True].id;
c.Service_Contract__c = [select Id from ServiceContract where AccountId = :c.AccountId and Primary_Service_Contract__c = True limit 1].id;
}catch(QueryException e) {
//No records found. Maybe you should set it to Null
}
}
}
}
}

Is there a trigger log
 

 

Best Answer chosen by Peter Cowen
Mahesh DMahesh D
Hi Peter,

Please find the below modified trigger:

 Here I covered:

(1) Added few comments.
(2) Replaced the RecordType Query with Scema object.
(3) Followed the proper naming convention.
(4) Proper Alignment.
(5) Bulkified the trigger.

What you need to do is:

(1) Change the record type name.
(2) Make sure that the API names of Objects and Fields are proper.
(3) Also clarify the requirement, whether we have to do this as part of Insert only or update also.

 
trigger UpdateServiceContract on Case (before insert, before update, after update) {
    
    Map<String, Schema.RecordTypeInfo> recordTypeNameMap = Schema.getGlobalDescribe().get('Case').getDescribe().getRecordTypeInfosByName(); 
    Id caseRecordTypeId = recordTypeNameMap.get('NameOfRecordType').getRecordTypeId();
        
    
    if (Trigger.isBefore && Trigger.isInsert) {
        Set<ID> setAccID = new Set<ID>();
        List<Case> finalCaseList = new List<Case>();
        // Iterate through input records.
        for (Case c : trigger.new) {
            if (c.RecordTypeID == caseRecordTypeId ) {
                if (c.service_contract__c == NULL && c.AccountId != null) {
                    setAccID.add(c.AccountId);
                    finalCaseList.add(c);
                }
            }   
        }
        // Check if Set is having values or not.
        if(!setAccID.isEmpty()) {
            Map<ID, Service_Contract_c> mapAccWiseServiceContract = new Map<ID, Service_Contract_c>() ;
            
            for(Service_Contract_c sc :  [Select Id, AccountId from Service_Contract_c where AccountId = :setAccID and Primary_Service_Contract__c = True] ) {
                mapAccWiseServiceContract.put(sc.AccountId, sc);
            }
            
            for (Case c : finalCaseList) {
                if(mapAccWiseServiceContract.get(c.AccountId) != null) {
                    c.Service_Contract__c = mapAccWiseServiceContract.get(c.AccountId).Id;
                }
            }
        }
    }
}

Please do let me know if it helps you.

Regards,
Mahesh

All Answers

GauravTrivediGauravTrivedi
Are you getting any error? 
Amit Chaudhary 8Amit Chaudhary 8
Two issue i found in your code.
1) Hard code ID
2) SOQL inside for loop

Try to change your code like below
trigger UpdateServiceContract on Case (before insert,before update, after update) 
{
	Id caseRecordTypeId = [Select id from RecordType where sObjectType = 'Case' and developerName ='NameOfRecordType' ].id ; 
	
	if (trigger.isBefore && trigger.isInsert) 
	{
		Set<ID> setAccID = new Set<ID>();
		for (Case c : trigger.new) 
		{
			if (c.RecordTypeID == caseRecordTypeId )
			{
				if (c.service_contract__c == NULL)
				{
					setAccID.add(setAccID);
				}
			}	
		}
		
		List<ServiceContract> lstServiceContract = [ select Id,AccountId from ServiceContract where AccountId = :setAccID and Primary_Service_Contract__c = True  ];
		
		Map<ID,ServiceContract> mapAccWiseServiceContract = new Map<ID,ServiceContract>() ;
		
		
		for(ServiceContract sc :  lstServiceContract )
		{
			mapAccWiseServiceContract.put(sc.AccountId ,ServiceContract );
		}
		
		for (Case c : trigger.new) 
		{
			if (c.RecordTypeID == caseRecordTypeId )
			{
				if (c.service_contract__c == NULL)
				{
					if(mapAccWiseServiceContract.containsKey(c.AccountId) )
					{
						c.Service_Contract__c = mapAccWiseServiceContract.get(c.AccountId).id;
					}
				}
			}
		}
	}
}
Please check below post to learn about trigger best pratice . I hope that will help you
1) http://amitsalesforce.blogspot.com/2015/06/trigger-best-practices-sample-trigger.html

Let us know if this will help you

Thanks
Amit Chaudhary
 
Mahesh DMahesh D
Hi Peter,

Please find the below modified trigger:

 Here I covered:

(1) Added few comments.
(2) Replaced the RecordType Query with Scema object.
(3) Followed the proper naming convention.
(4) Proper Alignment.
(5) Bulkified the trigger.

What you need to do is:

(1) Change the record type name.
(2) Make sure that the API names of Objects and Fields are proper.
(3) Also clarify the requirement, whether we have to do this as part of Insert only or update also.

 
trigger UpdateServiceContract on Case (before insert, before update, after update) {
    
    Map<String, Schema.RecordTypeInfo> recordTypeNameMap = Schema.getGlobalDescribe().get('Case').getDescribe().getRecordTypeInfosByName(); 
    Id caseRecordTypeId = recordTypeNameMap.get('NameOfRecordType').getRecordTypeId();
        
    
    if (Trigger.isBefore && Trigger.isInsert) {
        Set<ID> setAccID = new Set<ID>();
        List<Case> finalCaseList = new List<Case>();
        // Iterate through input records.
        for (Case c : trigger.new) {
            if (c.RecordTypeID == caseRecordTypeId ) {
                if (c.service_contract__c == NULL && c.AccountId != null) {
                    setAccID.add(c.AccountId);
                    finalCaseList.add(c);
                }
            }   
        }
        // Check if Set is having values or not.
        if(!setAccID.isEmpty()) {
            Map<ID, Service_Contract_c> mapAccWiseServiceContract = new Map<ID, Service_Contract_c>() ;
            
            for(Service_Contract_c sc :  [Select Id, AccountId from Service_Contract_c where AccountId = :setAccID and Primary_Service_Contract__c = True] ) {
                mapAccWiseServiceContract.put(sc.AccountId, sc);
            }
            
            for (Case c : finalCaseList) {
                if(mapAccWiseServiceContract.get(c.AccountId) != null) {
                    c.Service_Contract__c = mapAccWiseServiceContract.get(c.AccountId).Id;
                }
            }
        }
    }
}

Please do let me know if it helps you.

Regards,
Mahesh
This was selected as the best answer
Amit Chaudhary 8Amit Chaudhary 8
Two issue i found in your code.
1) Hard code ID
2) SOQL inside for loop

Try to change your code like below . I did minor change in below triger
trigger UpdateServiceContract on Case (before insert,before update, after update) 
{
	Id caseRecordTypeId = [Select id from RecordType where sObjectType = 'Case' and developerName ='NameOfRecordType' ].id ; 
	
	if (trigger.isBefore && trigger.isInsert) 
	{
		Set<ID> setAccID = new Set<ID>();
		for (Case c : trigger.new) 
		{
			if (c.RecordTypeID == caseRecordTypeId )
			{
				if (c.service_contract__c == NULL && c.AccountId)
				{
					setAccID.add(c.AccountId);
				}
			}	
		}
		
		List<ServiceContract> lstServiceContract = [ select Id,AccountId from ServiceContract where AccountId = :setAccID and Primary_Service_Contract__c = True  ];
		
		Map<ID,ServiceContract> mapAccWiseServiceContract = new Map<ID,ServiceContract>() ;
		for(ServiceContract sc :  lstServiceContract )
		{
			mapAccWiseServiceContract.put(sc.AccountId ,ServiceContract );
		}
		
		for (Case c : trigger.new) 
		{
			if (c.RecordTypeID == caseRecordTypeId )
			{
				if ( c.service_contract__c == NULL && c.AccountId != null )
				{
					if(mapAccWiseServiceContract.containsKey(c.AccountId) )
					{
						c.Service_Contract__c = mapAccWiseServiceContract.get(c.AccountId).id;
					}
				}
			}
		}
	}
}

NOTE:- Code i created on notepad. you may get some syntex issue

Thanks
Amit Chaudhary
amit.salesforce21@gmail.com
 
Peter CowenPeter Cowen
On the off chance does anyone know how to get the service contract to populate if just the contact has been added?
Mahesh DMahesh D
Hi Peter,

Did you try the code which I posted?

What is the issue you are facing?

Regards,
Mahesh
Peter CowenPeter Cowen
I am just trying it now. So far I can get it to work when adding the account manually but when adding the contact without account it will not populate.
Mahesh DMahesh D
Here the Service Contract will be populated on Case only when the Case is having an Account. Retrieving the Service Contracts based on given Account Id.

Please do let us know what is your actual requirement and possible scenarios so that we can help you.

Regards,
Mahesh
Peter CowenPeter Cowen
I would like the service contract to be populated when a case is created by a customer or by the support agents. So far the service contract populates when we add a contact including the account or just the account name which is great but I would like it to populate the service contract when a case is created by email or by the portal. It adds the account name and contact name. I don’t understand the inner workings of the portal or email to see what is added first the contact or the account. If populating the service contract when a case is created using email or portal do tell me.