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
BennettTranBennettTran 

Trigger Error Message: Nested IF Loop

Hello,

 

I am fairly new to APEX and have recently ran into an error when trying to do a mass upload using dataloader.  I have found that the error is because I have an IF statement within a FOR loop and was hoping someone could help me take the IF statement out with different logic?  My code is below and I have highlighted the IF statement in red that is looping through.  Thanks in advance.

 

 

trigger ImplementationCaseforIntegrationProducts on Opportunity (after insert, after update) {

string recordtype = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Implementation').getRecordTypeId();
List<Case> cases = new List<Case>();
List<Task> tasksList = new List<Task>();
for (Opportunity opp: Trigger.New){
case newcase= new case();
if(opp.AccountId != null){
Account a = [select id,name,Closed__c,ImplementationCaseCreated__c,Implementation_Specialist__c from Account where id =: opp.AccountId limit 1]; //This line more than enough to check in common, because if account id in opportunity is not null means only one value going to be there.

if((trigger.isInsert && (opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment'))&& opp.Integration_Product_Attached__c == True)||
(trigger.isUpdate && (opp.StageName != Trigger.oldMap.get(opp.Id).StageName && opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment')) && opp.Integration_Product_Attached__c == True))
{
if ((a.Closed__c == TRUE && a.implementationcasecreated__c == TRUE) || (a.ImplementationCaseCreated__c == False)){
newcase.AccountId=opp.AccountId;
newcase.Opportunity__c=opp.Id;
newcase.Subject='New Implementation case for '+opp.Account_Name__c;
newcase.Status='New';
newcase.Origin='Sign Up Form';
newcase.Priority='Medium';
newcase.RecordTypeId=recordtype;
newcase.Billing_Email__c = opp.Billing_Email__c;
newcase.ContactID = opp.PrimaryContactID__c;
cases.add(newcase);
}
else{
Task t = new Task(ownerId = a.Implementation_Specialist__c, Subject = 'Integration Sale', status = 'Not Started',
Priority = 'High', whatID = opp.Accountid, ActivityDate = Date.Today()); //You can change values accordingly
tasksList.add(t);
}
}
}
}

if(cases.size() > 0){
insert cases;
}
if(tasksList.size() > 0){
insert tasksList;
}
}

Best Answer chosen by BennettTran
digamber.prasaddigamber.prasad

Hi,

 

I have modified your trigger to make it bulk safe

 

trigger ImplementationCaseforIntegrationProducts on Opportunity (after insert, after update) {
	string recordtype = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Implementation').getRecordTypeId();
	List<Case> cases = new List<Case>();
	List<Task> tasksList = new List<Task>();
	Set<Id> setAccountId = new Set<Id>();
	
	for (Opportunity opp: Trigger.New){
		setAccountId.add(opp.AccountId);
	}
	Map<Id, Account> mapAccount = new Map<Id, Account>([select id,name,Closed__c,ImplementationCaseCreated__c,Implementation_Specialist__c from Account where id in: setAccountId]);
	
	for (Opportunity opp: Trigger.New){
		case newcase= new case();
		if(opp.AccountId != null){
			if(mapAccount.containsKey(opp.AccountId)){
				Account a = mapAccount.get(opp.AccountId);
				
				if((trigger.isInsert && (opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment'))&& opp.Integration_Product_Attached__c == True)||
				(trigger.isUpdate && (opp.StageName != Trigger.oldMap.get(opp.Id).StageName && opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment')) && opp.Integration_Product_Attached__c == True))
				{
					if ((a.Closed__c == TRUE && a.implementationcasecreated__c == TRUE) || (a.ImplementationCaseCreated__c == False)){
						newcase.AccountId=opp.AccountId;
						newcase.Opportunity__c=opp.Id;
						newcase.Subject='New Implementation case for '+opp.Account_Name__c;
						newcase.Status='New';
						newcase.Origin='Sign Up Form';
						newcase.Priority='Medium';
						newcase.RecordTypeId=recordtype;
						newcase.Billing_Email__c = opp.Billing_Email__c;
						newcase.ContactID = opp.PrimaryContactID__c;
						cases.add(newcase);
					}
					else{
						Task t = new Task(ownerId = a.Implementation_Specialist__c, Subject = 'Integration Sale', status = 'Not Started',
						Priority = 'High', whatID = opp.Accountid, ActivityDate = Date.Today()); //You can change values accordingly
						tasksList.add(t);
					}
				}
			}
		}
	}

	if(cases.size() > 0){
		insert cases;
	}
	if(tasksList.size() > 0){
		insert tasksList;
	}
}

 

Let me know if you still see any issue.

 

Happy to help you!

 

All Answers

digamber.prasaddigamber.prasad

Hi,

 

I have modified your trigger to make it bulk safe

 

trigger ImplementationCaseforIntegrationProducts on Opportunity (after insert, after update) {
	string recordtype = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Implementation').getRecordTypeId();
	List<Case> cases = new List<Case>();
	List<Task> tasksList = new List<Task>();
	Set<Id> setAccountId = new Set<Id>();
	
	for (Opportunity opp: Trigger.New){
		setAccountId.add(opp.AccountId);
	}
	Map<Id, Account> mapAccount = new Map<Id, Account>([select id,name,Closed__c,ImplementationCaseCreated__c,Implementation_Specialist__c from Account where id in: setAccountId]);
	
	for (Opportunity opp: Trigger.New){
		case newcase= new case();
		if(opp.AccountId != null){
			if(mapAccount.containsKey(opp.AccountId)){
				Account a = mapAccount.get(opp.AccountId);
				
				if((trigger.isInsert && (opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment'))&& opp.Integration_Product_Attached__c == True)||
				(trigger.isUpdate && (opp.StageName != Trigger.oldMap.get(opp.Id).StageName && opp.StageName.toLowerCase().equals('closed won'))&&(opp.Type.toLowerCase().equals('adjustment')) && opp.Integration_Product_Attached__c == True))
				{
					if ((a.Closed__c == TRUE && a.implementationcasecreated__c == TRUE) || (a.ImplementationCaseCreated__c == False)){
						newcase.AccountId=opp.AccountId;
						newcase.Opportunity__c=opp.Id;
						newcase.Subject='New Implementation case for '+opp.Account_Name__c;
						newcase.Status='New';
						newcase.Origin='Sign Up Form';
						newcase.Priority='Medium';
						newcase.RecordTypeId=recordtype;
						newcase.Billing_Email__c = opp.Billing_Email__c;
						newcase.ContactID = opp.PrimaryContactID__c;
						cases.add(newcase);
					}
					else{
						Task t = new Task(ownerId = a.Implementation_Specialist__c, Subject = 'Integration Sale', status = 'Not Started',
						Priority = 'High', whatID = opp.Accountid, ActivityDate = Date.Today()); //You can change values accordingly
						tasksList.add(t);
					}
				}
			}
		}
	}

	if(cases.size() > 0){
		insert cases;
	}
	if(tasksList.size() > 0){
		insert tasksList;
	}
}

 

Let me know if you still see any issue.

 

Happy to help you!

 

This was selected as the best answer
1ne-Up1ne-Up

Hello,

 

Can you post the error message you are encountering in dataloader?  If you are loading more than 100 records then you're probably hitting the 101 soql error message.  As you're looping through each opportunity, you're querying the account object based on the opp.AccountId value.  This type of logic is not recommended as you'll run into SFDC governor limits.

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm

 

Proposed logic update:

For each opportunity, perform the following steps:

If accountId is not null, add to list.

Make one soql query against the account abject using the list populated above.

Loop through queried accounts and loop through opportunities (trigger.new)

If accountId == opp.AccountId, perform remaining checks and create new case/task.

 

Thanks

Himanshu