Skip to main content
Kim Roberts (PrismHR) ha preguntado en #Apex
Hi - wondering if someone could give some guidance.  I am not a developer or programmer but have someone on site that has some programming background and has made some headway on other Apex errors.  But this one is a bit more challenging.

We have a custom object called "Known Issues", on the community, the users can "subscribe" either to "Each Known Issue" and/or a "Weekly KI Report".  It seems that as we have had more users subscribe, it is now timing out.  We first noticed this with our ServiceRocket Jira SF Connector (we used to create them in Jira, push to SF), now just by trying to create a new KI directly in SF.

From what I can tell, we have 1 trigger, 1 trigger handler and a few other classes.  But we are not sure if it is just the trigger handler that has to be adjusted (and if so, how).

Here are the errors:

Errors pushing over corrected Apex Classes

All but one references the same KnownIssuesTriggerHandler.  My Director has been able to successfully test a solution to the Opportunity class, so we are focused on the other 3.

This is the trigger called KnownIssues (it only has 50% code coverage):

trigger KnownIssues on Known_Issues__c (after insert, after update) {

if(trigger.isInsert){

KnownIssuesTriggerHandler.handleInsert(Trigger.new, Trigger.oldMap, Trigger.operationType);

}else if(trigger.isUpdate){

KnownIssuesTriggerHandler.handleUpdate(Trigger.new, Trigger.oldMap, Trigger.operationType);

}

}

This is the KnownIssuesTriggerHandler.  It  has 64% code coverage:

/**

* @author Bluewolf @nathan.vass

* @date 6/2019

* @group Trigger Handler

* @description Trigger handler for KnownIssues

*/

public with sharing class KnownIssuesTriggerHandler {

public static Boolean bypassTrigger = false;

public static void handleInsert(List<Known_Issues__c> newRecords, Map<Id, Known_Issues__c> oldRecords, System.TriggerOperation triggerEvent ) {

//query all users that have the "Subscribe to Each Known Issue" field checked

List<String> toAddresses = new List<String>();

List<Messaging.SingleEmailMessage> allmsg = new List<Messaging.SingleEmailMessage>();

EmailTemplate notifTemplate = [SELECT Id, Name, Subject, Body FROM EmailTemplate WHERE Name = 'Known Issues Created Template' LIMIT 1];

OrgWideEmailAddress noReplyAddress = [SELECT Id from OrgWideEmailAddress where Address = 'noreply@prismhr.com' LIMIT 1];

List<User> sendKnownIssueNotifToUsers = [SELECT Id, Email FROM User WHERE Subscription_to_Each_New_Known_Issue__c = true];

for(Known_Issues__c newKnownIssue : newRecords) {

for(User u : sendKnownIssueNotifToUsers) {

Messaging.SingleEmailMessage mail = Messaging.renderStoredEmailTemplate(notifTemplate.Id, u.Id, newKnownIssue.Id);

String emailSubject = mail.getSubject();

String emailTextBody = mail.getPlainTextBody();

mail.setTargetObjectId(u.Id);

mail.setOrgWideEmailAddressId(noReplyAddress.Id);

mail.setSubject(emailSubject);

mail.setPlainTextBody(emailTextBody);

mail.setSaveAsActivity(false);

allmsg.add(mail);

}

System.debug('sending email');

List<Messaging.SendEmailResult> results = Messaging.sendEmail(allmsg, false);

for(Messaging.SendEmailResult emailResult : results){

if(emailResult.IsSuccess()) {

System.debug('Email result ' + emailResult.IsSuccess());

} else {

for (Messaging.Sendemailerror sendEmailError : emailResult.getErrors()){

System.debug('Email error: ' + sendEmailError.getMessage());

}

}

}

}

}

public static void handleUpdate(List<Known_Issues__c> newRecords, Map<Id, Known_Issues__c> oldRecords, System.TriggerOperation triggerEvent ) {

if (bypassTrigger) {

return;

}

switch on triggerEvent {

when AFTER_UPDATE {

JiraSyncServices.pushKnownIssuesAffectedUsers(newRecords, oldRecords);

}

when else {

// do nothing

}

}

}

}

JiraSyncServices only has 7% code coverage:

/**

* @author Bluewolf @nathan.vass

* @date 6/2019

* @group Service

* @description sync salesforce with Jira

*/

public with sharing class JiraSyncServices {

@testVisible static IJiraPusher jiraPusher {

get {

if (jiraPusher == null) {

jiraPusher = new JiraPusherDefault();

}

return jiraPusher;

} set;

}

public static void pushKnownIssuesAffectedUsers(List<Known_Issues__c> newRecords, Map<Id, Known_Issues__c> oldMap) {

List<Known_Issues__c> affectedUsersChangedNewRecords = new List<Known_Issues__c>();

List<Known_Issues__c> oldRecordsChanged = new List<Known_Issues__c>();

for (Known_Issues__c newIssue : newRecords) {

Known_Issues__c oldIssue = oldMap.get(newIssue.Id);

if (newIssue.Number_of_Affected_Users__c != oldIssue.Number_of_Affected_Users__c) {

affectedUsersChangedNewRecords.add(newIssue);

oldRecordsChanged.add(oldIssue);

}

}

if (!affectedUsersChangedNewRecords.isEmpty()) {

jiraPusher.push(affectedUsersChangedNewRecords, oldRecordsChanged);

}

}

}

This is the JiraSyncServicesTest:

/**

* @author Bluewolf @nathan.vass

* @date 6/2019

* @group Test

* @description test for JiraSyncServices

*/

private @isTest class JiraSyncServicesTest {

static final Integer RECORD_COUNT = 2;

@isTest static void pushKnownIssuesAffectedUsers_onlyChangedAffectedUsersSynced() {

JiraPusherMock pusherMock = new JiraPusherMock();

JiraSyncServices.jiraPusher = pusherMock;

List<Known_Issues__c> issues = new SObjectBuilder(Known_Issues__c.SObjectType)

.count(RECORD_COUNT).create().getRecords();

Known_Issues__c withAffectedUsers = issues[0];

List<Affected_Users__c> affectedUsers = new SObjectBuilder(Affected_Users__c.SObjectType)

.put(Affected_Users__c.Known_Issue__c, withAffectedUsers.Id)

.count(RECORD_COUNT).build().getRecords();

Test.startTest();

insert affectedUsers;

Test.stopTest();

System.assertEquals(1, pusherMock.newIssues.size(),

'When a Know Issue in salesforce has a change in its affected users count, Jira should be updated');

Known_Issues__c newIssueSynced = pusherMock.newIssues[0];

Known_Issues__c oldIssuesSynced = pusherMock.oldIssues[0];

System.assertEquals(withAffectedUsers.Id, newIssueSynced.Id,

'When a Know Issue in salesforce has a change in its affected users count, Jira should be updated');

System.assertEquals(RECORD_COUNT, newIssueSynced.Number_of_Affected_Users__c,

'Jira needs to know the current state of the affected users count');

System.assertEquals(0, oldIssuesSynced.Number_of_Affected_Users__c,

'Jira needs to know the previous state of the affected users count');

}

class JiraPusherMock implements IJiraPusher {

public List<Known_Issues__c> newIssues = new List<Known_Issues__c>();

public List<Known_Issues__c> oldIssues = new List<Known_Issues__c>();

public void push(List<SObject> newRecords, List<SObject> oldRecords) {

this.newIssues = newRecords;

this.oldIssues = oldRecords;

}

public void push() {}

}

}

​​​​​​​I am not sure if that is enough info to help.  I really appreciate anyone's thoughts or direction.  Please keep in mind we do not have a developer, we are working through this as best we can with documentation.  As explicit you can be with directions, the better.  Thank you so much in advance -

​​​​​​​Kim

 
1 respuesta
  1. 12 jul 2020, 18:53
    Hi Kim,

    i have narrowed down your issue to this line of code 

     Messaging.SingleEmailMessage mail = Messaging.renderStoredEmailTemplate(notifTemplate.Id, u.Id, newKnownIssue.Id);

    As per salesforce doc :https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_messaging.htm

    renderStoredEmailTemplate   count against soql limit  so whenever  you have many users like more than 100 , you will hit soql limits.

    I would suggest dont use   renderStoredEmailTemplate  method. 

    Try to create email template in apex class itself and  modify this method.

     
0/9000