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
ajbtv2ajbtv2 

Mass Update with SingleEmail Trigger

I need some assistance bulkifing a trigger.

 

I have been tasked with setting up a Fulfillment Email trigger that notifies end users when an Asset has been shipped.

 

I have found I need to use the SingleEmail method due to needed to Mail Merge Asset Fields.

 

The system must identify the contact on the Asset, the Contacts in a group associated to the Asset, the contacts on the account requesting all notices sent, and if a web fulfillment all users in the Public Group associated to the account.

 

The trigger works well if I am updating a single record at a time.  I run into issues when my vendor asset also updates all associated records for other accounts giving me a 101 SOQL error.

 

I have been able to remove the error by updating out of the for loop, but the emails now only go to the first account (as expected) [0].

 

I have thought about running a schedule apex class, but if I can only send 2 or 3 notices at a time, that will take too long to complete.

 

Any assistance is greatly appriciated.  I have posted my WIP code below:

 

----- REMOVED CODE AS UPDATE IS AVAILABLE BELOW  ----- 

UVUV

You are getting 101 SOQL query error because you are hitting limit.

In single context there can be exceution of 100 queries.I reviewed your code and found that you are using queries within loop and that is not best practice.I would suggest you to get information in list/variable out side the loop and then assign within loop.

 

Hope this works for you.

 

ajbtv2ajbtv2

Besides the email templates, which I corrected without success, where do I have queries in for loops?

 

Also, right now the code only works for the first item in the list when sending out a single email.  How can get the code to send out multiple single emails to the correct contacts when doing a bulk update?  It will send out 8 emails when the code fires, but all 8 emails go to the same contact.  It should be 8 different Asset Records to 8 different Account/contacts.

 

I know I am hitting my limit.  My question is how do I get the code to operate without hitting that limit.

 

Thanks

ajbtv2ajbtv2

Here is my most current Code.

 

The code currently works because I have told it not to collect the information or send the emails for 'Vendor Letter'.

 

If I take that statement out, the system sends out multiple emails (depending on number of Assets) to only the first Asset information in the list.

 

I now have a strange occurrance where the After Update email is being activated twice.

 

If I move the vup2 update to inside the for loop so it will actually collect the correct information for each Asset it works.

 

Really, I need the for loop to collect the Contacts needed for each Asset, but that runs me passed the 100 SOQL easily on a mass update.

 

I have begun looking at the @future statement and running a class instead of a trigger, but I am unfamiliar with the @future statement

 

trigger FulfillmentEmail on Asset (before update, after update) {


List<String> toAddresses = New List<String>();
List<String> CCAddresses = New List<String>();

Asset[] ful = trigger.new;

Contact defcon = [Select c4.id from Contact c4 where c4.Org_Wide_Fulfillment_Contact__c = true limit 1];

if(ful[0].Carrier__c != 'Vendor Letter'){

System.debug('ful:' + ful);
System.debug('ful-0:' + ful[0]);
//Account contacts requesting all Fulfillment Notices
List<Contact> actcont = [Select c.id, c.email from Contact c where c.Fulfillment_Notifications__c = true and c.Inactive_Contact__c = false and c.AccountId IN (Select id from Account where id IN :ful)];
System.debug('actcont1' + actcont);

List<String> gname = New List<String>();
for(Asset fq : trigger.new){
gname.add(fq.Account_Sharing_Group__c);
}
system.debug('gname:' + gname);
//Group for Fulfillment
List<Group> g = [Select g.id from Group g where g.Type='Regular' and g.Name IN :gname];
if (ful[0].Carrier__c == 'Web'){
	if (g.IsEmpty() == true){
		ful[0].addError('A Workspace Group has not been established.');
	}

  System.debug(g); 
   if(g.IsEmpty() == false){
 List<Id> gmemberIds = new List<Id>();   	
 for(GroupMember gm : [Select gm.UserOrGroupId from GroupMember gm where gm.GroupId IN :g]){
    gmemberIds.add(gm.UserOrGroupId);
   System.debug('gm:' + gm);
 }
  System.debug('g:' + g);
 for(Group g2 : [Select g2.RelatedId from Group g2 where g2.id IN :gmemberIds]){
    gmemberIds.add(g2.RelatedId);
 }
 for(User u2 : [Select u2.Email from User u2 where u2.IsActive = true and u2.UserRoleId IN :gmemberIds]){
    toAddresses.add(u2.Email);
 }
 for(User u : [Select u.Email from User u where u.IsActive = true and u.id IN :gmemberIds]){
     toAddresses.add(u.Email);
                               }
   }

}

//Gather Notification Contacts from Fulfillment Line
//List<Fulfillment_Contact__c> nfcont = [Select Contact__c from Fulfillment_Contact__c where Fulfillment_Group__c = :ful[0].Fulfillment_Group__c];
//List<Id> nfcont2 = [Select id from Contact where id IN :nfcont.Contact__c];

//Gather Contact from Fulfillment Line
//nfcont.add(ful[0].ContactId);


//Contacts email Addresses
Set<Contact> allcons = New Set<Contact>();
for(Contact c2 : actcont){
	allcons.add(c2);
}
for(Contact c3 : [Select id from Contact where id IN (Select ContactId from Asset where id IN :ful)]){
	if(c3 != null){
		allcons.add(c3);
	}
}
System.debug('actcont:' + actcont);
List<ID> fulgr = New List<Id>();
for(Asset asf : ful){
	fulgr.add(asf.Fulfillment_Group__c);
}
//Gather Notification Contacts from Fulfillment Line
for(Contact cal : [Select id from Contact where id IN (Select Contact__c from Fulfillment_Contact__c where Fulfillment_Group__c IN :fulgr)]){
   if(cal != null){
   	 allcons.add(cal);
   }
}
System.debug('allcons' + allcons);
//allcons.add('nfcont2' + nfcont2);

//Gather email from contacts
for(Contact tocons : [Select email from Contact where id in :allcons]){
	System.debug(tocons);
	if(tocons.Email != null){
		toAddresses.add(tocons.Email);
	}
}
//Gather FHOnline Users
//Acount contacts with an FH Online Account, but not requesting all Notices
if (ful[0].Carrier__c == 'FH Online'){
List<Contact> fhonline = [Select c.id, c.Email from Contact c where c.FH_Online_User__c = true and c.Fulfillment_Notifications__c = false and c.Inactive_Contact__c = false and c.AccountId IN (Select id from Account where id IN :ful)];
for(Contact fhusr : fhonline){
	if(fhusr.email != null){
		ccAddresses.add(fhusr.email);
	}
}
}

if(trigger.isBefore){
EmailTemplate etg = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeGround'];
EmailTemplate eto = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeOnline'];
EmailTemplate etv = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeVendorE'];
EmailTemplate etw = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeWeb'];

   for(Asset ff :trigger.new){
     if(ff.InstallDate != null && ff.Fulfillment_Notice_Sent__c == false){
        Messaging.SingleEmailMessage mail1 = new Messaging.SingleEmailMessage();
        if(ff.Carrier__c == 'Web'){
        mail1.setTemplateId(etw.id);
        }
        if(ff.Carrier__c == 'Vendor Letter'){
        mail1.setTemplateId(etv.id);
        }
        if(ff.Carrier__c == 'FH Online'){
        mail1.setTemplateId(eto.id);
        }
        if(ff.Carrier__c != 'Web' && ff.Carrier__c != 'Vendor Letter' && ff.Carrier__c != 'FH Online'){
        mail1.setTemplateId(etg.id);      
        }
        mail1.setTargetObjectId(defcon.id);
        mail1.setToAddresses(toAddresses);        
        if(ff.Carrier__c == 'FH Online'){
        mail1.setCCAddresses(ccAddresses);
        }
        mail1.setWhatId(ful[0].id);
        mail1.SaveAsActivity = true;
        mail1.setReplyTo('support@fairhealthus.org');
        mail1.setSenderDisplayName('Fair Health Fulfillments');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail1});
        
        ff.Fulfillment_Notice_Sent__c = true;
 
     }
   }
 }
}
if(Trigger.isAfter){
//Vendor contacts requesting all Fulfillment Notices
List<Contact> vendcont = [Select c.id, c.Email from Contact c where c.Fulfillment_Notifications__c = true and c.Inactive_Contact__c = false and c.AccountId IN (Select Vendor__c from Asset where id IN :ful)];
List<String> vendoraddresses = New List<String>();
for(Contact va : [Select Email from Contact where id in :vendcont]){
	if(va.Email != null){
		vendoraddresses.add(va.Email);
	}
}
	
	//Vendor Fulfillments

	if(ful[0].Vendor__c != null){
		//Gather Vendors Fulfillment Information
        List<Asset> vendorship = [Select AccountId, Scheduled_Release_Date__c, InstallDate, Product2Id, Fulfillment_Notice_Sent__c from Asset where AccountID = :ful[0].Vendor__c and Scheduled_Release_Date__c = :ful[0].Scheduled_Release_Date__c and Product2id = :ful[0].Product2Id];
        if(vendorship.isEmpty() == true){
           ful[0].adderror('The Vendor has not been fulfilled this product, you must fulfill the vendor first.');
        }
		if(vendorship.isEmpty() == false){
		if(vendorship[0].InstallDate == null && ful[0].InstallDate != null){
			ful[0].adderror('The Vendor has not been fulfilled this product, you must fulfill the vendor first.');
		}
		if (vendorship[0].Fulfillment_Notice_Sent__c == true && ful[0].InstallDate > vendorship[0].InstallDate){
        Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();
        EmailTemplate et = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeVendorU'];
        mail2.setTemplateId(et.id);
        mail2.setTargetObjectId(defcon.id);
        mail2.setToAddresses(vendorAddresses);
        mail2.setWhatId(ful[0].Id);
        mail2.SaveAsActivity = true;
        mail2.setReplyTo('support@fairhealthus.org');
        mail2.setSenderDisplayName('Fair Health Fulfillments');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail2});
        }		
    }
	}
    if(ful[0].Authorized_Vendor__c == 'True'){
    List<Asset> vendrelate = [Select id, Product2Id, InstallDate, Status, Carrier__c, Scheduled_Release_Date__c from Asset where Product2Id = :ful[0].Product2Id and Scheduled_Release_Date__c = :ful[0].Scheduled_Release_Date__c and Vendor__c = :ful[0].AccountId];
    List<Asset> assetstoupdate = New List<Asset>{};
system.debug('vendrelate:' + vendrelate);
         for(Asset vup2 : vendrelate){
         	system.debug('vup2' + vup2);
    if(ful[0].InstallDate != null && ful[0].Scheduled_Release_Date__c != null && ful[0].Product2Id == vup2.Product2Id && ful[0].Scheduled_Release_Date__c == vup2.Scheduled_Release_Date__c && vup2.InstallDate == null){
        vup2.InstallDate = system.today();
        vup2.Status = 'Shipped';
        vup2.Carrier__c = 'Vendor Letter';
       assetstoupdate.add(vup2);
//          update vup2;
    }
         }
         update assetstoupdate;
     }
 
 //Email vendor authorization letter
 for(Asset vsend : ful){
 	Asset bfup = System.Trigger.oldMap.get(vsend.id);
   if(vsend.Authorized_Vendor__c == 'True' && vsend.InstallDate == system.today() && bfup.Fulfillment_Notice_Sent__c == false){
    Messaging.SingleEmailMessage mail3 = new Messaging.SingleEmailMessage();
        EmailTemplate et = [Select id FROM EmailTemplate WHERE developerName = 'FulfillmentNoticeVendor'];
        mail3.setTemplateId(et.id);
        mail3.setTargetObjectId(defcon.id);
        mail3.setToAddresses(toAddresses);
        mail3.setWhatId(vsend.AccountId);
        mail3.SaveAsActivity = true;
        mail3.setReplyTo('support@fairhealthus.org');
        mail3.setSenderDisplayName('Fair Health Fulfillments');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail3});
   }

      }
	}
  }