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
kevin.chileskevin.chiles 

Trying to manipulate my email opt out on person accounts when a case is open for that Accounts

Hello

 

I am trying to make sure that if a case is open for an account that they cannot be contacted.  This is what I have so far, but it does not seem to work.  Once the case is closed an no other open cases exist, the check box should be removed

 

trigger DoNotContactAccount on Case (after insert, after update) {
List<Account> updateAccList = new List<Account>();

//Loop through the case and update the account with appropriate category
set<ID> AccIds = new set<ID>();
for( Case c1 : Trigger.New){
if(c1.AccountId != null && c1.Do_Not_Contact__c != null)
AccIds.add(c1.AccountID);
}
if(!AccIds.isEmpty()){
list<Case> caseList = [select AccountID, Do_Not_Contact__c from Case where AccountId = : AccIds];
map<Id, Account> AccountUpdates = new map<ID, Account>();
for(Case cs : caseList){
Account acc = AccountUpdates.get(cs.AccountID);
if(acc == null)
acc = new Account(Id = cs.AccountId);

if(cs.Status != 'Closed')
acc.PersonHasOptedOutOfEmail = true;
else
acc.PersonHasOptedOutOfEmail = false;

AccountUpdates.put(cs.AccountID, acc);
}

update AccountUpdates.Values();
}
}

Best Answer chosen by Admin (Salesforce Developers) 
kevin.chileskevin.chiles

WOOHOOOOOOO!!!  I was able to get this code to work.  Much easier and totally facilitates the need.

 

trigger donotcontactaccount on Case (after insert, after update) {

for (Case c : Trigger.new) {
Account a = [Select Id From Account Where Id = :c.AccountId];
if (c.status == 'New' || c.status == 'Pending' || c.status == 'Escalated') {
a.Do_Not_Contact__c = true;
update a;
}
else {
Case[] allCases = [Select Id, Status From Case Where AccountId = :a.Id];
Integer i = 0;
for (Case c1 : allCases) {
if (c.status != 'New' && c.status != 'Pending' && c.status != 'Escalated') {
i++;
}
}
if (i > 0) {
// all cases do not meet the criteria, so Do_Not_Contact__c = false
a.Do_Not_Contact__c = false;
update a;
}

}

}

}

 

All Answers

AdrianCCAdrianCC

Hi,

 

Try this:

trigger DoNotContactAccount on Case (after insert, after update) {
	
	Set<Id> accIds = new Set<Id>();
	for ( Case cs: Trigger.new) {
		if (cs.AccountId != null && cs.Do_Not_Contact__c == true) { //isn't Do_Not_Contact__c a checkbox?
			accIds.add(cs.AccountId);
		}
	}

	if(!accIds.isEmpty()){
		Map<Id, Account> accountsMap = new Map<Id, Account>([SELECT Id, PersonHasOptedOutOfEmail FROM Account WHERE Id IN:accIds]);//use the IN operator
		List<Case> allCasesList = [SELECT Id, AccountId, Do_Not_Contact__c FROM Case WHERE AccountId IN:accIds];

		//we need a map of Account Id to list of related Cases for that Account to make sure that once the case it is closed and no other open case exist
		//the PersonHasOptedOutOfEmail is set to false, otherwise true
		Map<String, List<Case>> accIdToRelatedCasesMap = new Map<String, List<Case>>();
		for (Case cs: allCasesList) {
			if (accIdToRelatedCasesMap.get(cs.AccountId)) == null) {
				List<Case> newCasesList = new List<Case>();
				newCasesList.add(cs);
				accIdToRelatedCasesMap.put(cs.AccountId, newCasesList);
			} else {
				accIdToRelatedCasesMap.get(cs.AccountId).add(cs);
			}
		}
		
		List<Account> updateAccList = new List<Account>();
		
		for (Case cs : Trigger.new) {

			//for each record, we check the related cases to see if there are any not closed
			if (cs.AccountId != null && cs.Do_Not_Contact__c == true) { 
				Boolean allClosed = false;
				for (Case relatedCase: accIdToRelatedCasesMap.get(cs.AccountId)) {
					if (relatedCase.Status == 'Closed') {
						allClosed = true;
					} else {
						allClosed = false;
						break;//we get out of the cycle since we found an opened related case
					}
				}

				Account a = accountsMap.get(cs.AccountId);
				a.PersonHasOptedOutOfEmail = allClosed;
				updateAccList.add(a);
			}
		}

		update updateAccList;
	}
}

 Check out the comments and ask me if you have any questions.

 

Ty,

Adrian

 

PS: always test your classes(&triggers) with test classes. That's the simplest way to find issues

PPS:Happy Monday! :)

kevin.chileskevin.chiles

Line 18 gives me an unexpected token error for '=='

kevin.chileskevin.chiles

Fixed that line 18 error.  Stand by for test

kevin.chileskevin.chiles

Hello!

 

I tested this and it did not fire as expected.  The Account field did not get updated upon the insert, or update of the case record.

kevin.chileskevin.chiles

Hello!!!!!  

 

After a few small changes(had to create a custom field for the account portion, as I am using business accounts, and person accounts)  here is the finished code.  And she is beautiful and works like a charm.

 

trigger DoNotContactAccount3 on Case (after insert, after update) {

Set<Id> accIds = new Set<Id>();
for ( Case cs: Trigger.new) {
if (cs.AccountId != null && cs.Do_Not_Contact__c != true) { //isn't Do_Not_Contact__c a checkbox?
accIds.add(cs.AccountId);
}
}

if(!accIds.isEmpty()){
Map<Id, Account> accountsMap = new Map<Id, Account>([SELECT Id, Do_Not_Contact__c FROM Account WHERE Id IN:accIds]);//use the IN operator
List<Case> allCasesList = [SELECT Id, AccountId, Do_Not_Contact__c FROM Case WHERE AccountId IN:accIds];

//we need a map of Account Id to list of related Cases for that Account to make sure that once the case it is closed and no other open case exist
//the PersonHasOptedOutOfEmail is set to false, otherwise true
Map<String, List<Case>> accIdToRelatedCasesMap = new Map<String, List<Case>>();
for (Case cs: allCasesList) {
if (accIdToRelatedCasesMap.get(cs.AccountId)== null) {
List<Case> newCasesList = new List<Case>();
newCasesList.add(cs);
accIdToRelatedCasesMap.put(cs.AccountId, newCasesList);
} else {
accIdToRelatedCasesMap.get(cs.AccountId).add(cs);
}
}

List<Account> updateAccList = new List<Account>();

for (Case cs : Trigger.new) {

//for each record, we check the related cases to see if there are any not closed
if (cs.AccountId != null && cs.Do_Not_Contact__c == true) {
Boolean allClosed = false;
for (Case relatedCase: accIdToRelatedCasesMap.get(cs.AccountId)) {
if (relatedCase.Status == 'Closed') {
allClosed = true;
} else {
allClosed = false;
break;//we get out of the cycle since we found an opened related case
}
}

Account a = accountsMap.get(cs.AccountId);
a.Do_Not_Contact__c = allClosed;
updateAccList.add(a);
}
}

update updateAccList;
}
}

 

 

Thank you so much for your help with this!  So many Props!

kevin.chileskevin.chiles

So yesterday when I was testing this it was working fine, now it seems to fail and not give me the expected result, the check box being either turned on or off within my enviroment.  My field Do_Not_contact__c on my cases object is a formula field that pulls from the do not contact on the account.  Is this the correct way to go about this?  How it field should work is, when a new case is created the account Do_Not_Contact__c should be marked as true, once the case is closed, it should be marked as false.  

kevin.chileskevin.chiles

WOOHOOOOOOO!!!  I was able to get this code to work.  Much easier and totally facilitates the need.

 

trigger donotcontactaccount on Case (after insert, after update) {

for (Case c : Trigger.new) {
Account a = [Select Id From Account Where Id = :c.AccountId];
if (c.status == 'New' || c.status == 'Pending' || c.status == 'Escalated') {
a.Do_Not_Contact__c = true;
update a;
}
else {
Case[] allCases = [Select Id, Status From Case Where AccountId = :a.Id];
Integer i = 0;
for (Case c1 : allCases) {
if (c.status != 'New' && c.status != 'Pending' && c.status != 'Escalated') {
i++;
}
}
if (i > 0) {
// all cases do not meet the criteria, so Do_Not_Contact__c = false
a.Do_Not_Contact__c = false;
update a;
}

}

}

}

 

This was selected as the best answer
kevin.chileskevin.chiles

Test Class for full coverage

 

@isTest(seeAllData=True)
private class testdonotcontactaccount{
static testMethod void donotcontactaccount(){


Account a = new Account (name='ABC');
a.Do_Not_Contact__c=false;

insert a;

Case c= new Case ();
c.Status = 'New';
c.AccountId = a.id;
c.Origin = 'Email';

insert c;

c.Status = 'Closed';

update c;

}
}

AdrianCCAdrianCC

Awesome :)