• Christine_K
  • NEWBIE
  • 30 Points
  • Member since 2014
  • Salesforce Developer
  • OTIP

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 9
    Replies
I'm trying to create a lightning component for a custom object called Comments__c.  Comments__c can be used for Accounts and/or Contacts.

I would like the LC to be dynamic enough where I just have one lightning component for both Accounts and Contacts.  The purpose of the lightning component is to display the comments on the record detail page of either the Account or Contact.  If it's a Contact Record, I would like to display the Account comments as well as the Contact comments.

I'm stuck as to how I can make this lightning component reusable for Contacts.  Here is my code thus far

ListComments.cmp
<aura:component controller = "CommentsController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="newComment" type="Object"/>
    <aura:attribute name="sObjects" type="sObject[]"/>
    <aura:attribute name="CommentList" type="Comment__c[]" />
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    
    <aura:if isTrue="{!not(empty(v.CommentList))}">
    <lightning:card>
        <aura:set attribute="actions">
            <ui:button label="New Comment" press="{!c.createRecord}"/>
        </aura:set>
        <p class="slds-p-horizontal_small slds-text-align_center">
            <aura:iteration  items="{!v.CommentList}" var="com">
                <div class="uiOutputRichText" linkify="true" >
                    <p><ui:outputRichText aura:id="outputRT" value="{!com.Comment__c}" /></p>
                </div>
            </aura:iteration>
        </p>
    </lightning:card>
    </aura:if>
    
    
</aura:component>

CommentsController.apxc
public with sharing class CommentsController {
@AuraEnabled
    public static list<Comment__c> getRelatedList(Id recordId)
    {
        List<Comment__c> commlist = [Select id, active__c, comment__c,contact__c,createdbyid,createddate from Comment__c where Account__c=: recordId AND Active__c = true ORDER BY CreatedDate ASC];
        return commlist;
    }
}

ListCommentsController.js
({
    myAction : function(component, event, helper) 
    {
        var commList = component.get("c.getRelatedList");
        commList.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        commList.setCallback(this, function(data) 
        {
             component.set("v.CommentList", data.getReturnValue());
        });
        $A.enqueueAction(commList);
    },
    createRecord : function (component, event, helper) {
        var createRecordEvent = $A.get("e.force:createRecord");
        createRecordEvent.setParams({
            "entityApiName": "Comment__c",
            "navigationLocation" : "LOOKUP",
            "defaultFieldValues":{
                "Account__c": component.get("v.recordId")
            },
            "panelOnDestroyCallback": function(event) {
                var urlEvent = $A.get("e.force:navigateToURL");
                urlEvent.setParams({
                    "url": "/lightning/r/Account/"+component.get("v.recordId")+"/view"
                });
                urlEvent.fire();
            }
        });
        createRecordEvent.fire();
        
    }
})


 
I was hoping to get some assistance with code coverage for a particular class.

In my trigger I have:
else if(Trigger.isDelete)
    {
        handler.clearAccountEmails(Trigger.old, Trigger.new, Trigger.oldMap);
    }
Trigger Handler:
public void clearAccountEmails(Contact[] oldContacts, Contact[] updatedContacts, Map<ID, Contact> oldContactsMap)
    {
        List<Account> accounts = new List<Account>();          
        for(Contact c : oldContacts)
        {
            if(c.AccountId != null && c.Primary_Contact__c)
            {
                Account a = new Account(id = c.AccountId);
                if(c.Email != null) a.Primary_Contact_Email_1__c = '';
                if(c.Email != null) a.Customer_Email__c = '';
                if(c.Email_2__c != null) a.Primary_Contact_Email_2__c = '';
                if(c.Servicing_Contact_Method__c  != null) a.Servicing_Contact_Method__c  = ''; 
                accounts.add(a);
            }  
        }
        
        if(!accounts.isEmpty())
        {
            try{
                update accounts;
            }
            catch(exception e){
                System.debug('The following exception has occurred: ' + e.getMessage());
            }
            system.debug(accounts);
        }

I can't seem to get code coverage for the above.  Any assistance would be greatly appreciated.

Thanks!

 
I'm working on a lightning component for the service cloud utility bar which should essentially auto log you into Omni Channel once you have been logged into the service console.

In the lightning component controller, I have the following:
({
    doInit: function(cmp, evt, hlp) {
        window.setTimeout(
            $A.getCallback(function() {
                
                var omniAPI = cmp.find("omniToolkit");
                omniAPI.setServicePresenceStatus({
                    statusId: "0N561000000027Y",
                    callback: function(result) {
                        if (result.success) { 
                            console.log('Set status successful');
                            console.log('Current statusId is: ' + result.statusId);
                            console.log('Channel list attached to this status is: ' + result.channels); 
                        } else {
                            console.log('Set status failed');
                        }
                    }
                });
                
                
            }), 100
        ) 
     //helper.setStatus(cmp, evt, hlp);
    },  
})
In my component I have:
<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
   
 <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <lightning:omniToolkitAPI aura:id="omniToolkit" />
    <!--
        <lightning:utilityBarAPI aura:id="utilitybar" />
        <lightning:button label="Get Status" onclick="{! c.getStatus }" />
        <lightning:button label="Set Status" onclick="{! c.setStatus }" />
  -->
</aura:component>
How do I go about getting this to load automatically? If I click on the lightning component, I will get signed into Omni-channel.  It would be ideal to have this happen on load.



 
Hello,

I'm trying to implement a Activities Reminder component that displays in the footer bar of the Salesforce Console.  I have the Reminders window displaying open activities.  As long as I already have a tab open and I click on an activity name, the window will open in the console.

If I have no tabs open and click on an activity from the Reminders component, the activity doesn't display but instead I get an error "getPageInfo: Invalid Parameter Value: scc-pt-1"

Is there a way to open the activity in the console without having a tab already open?

Thanks!
I'm having a bit of trouble writing a test class for the Messaging.InboundEmailHandler class.  I am stuck at 44%.  Any suggestions on how I can achieve 100% code coverage would be greatly appreciated.

Apex Class
// Apex class used to capture reply emails from clients and attach 
// to their lead record
// A task is created against the lead record with the 
// contents of the reply email
// A workflow has also been created to notify the lead
// owner that a new inbound email has been created
global class ProcessReplyEmails implements Messaging.InboundEmailHandler {
    
    Global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope env ) {
        
        // Create an inboundEmailResult object for returning 
        // the result of the email service.
        Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
        
        String mySubject = email.subject;
        String myPlainText = '';
        myPlainText = email.plainTextBody;
        
        // Capture the record ID from the subject line
        String refID = mySubject.right(15);
        System.debug('extract Subject: ' + refID);
        
        // New email task to be created
        Task[] newTask = new Task[0];
        try
        {
        	// Try to lookup the lead record that matches the ID in the subject
        	Lead l = [SELECT Id, Name, Email, Company, Phone, OwnerID FROM Lead WHERE ID = :refID];
            
            newTask.add(new Task(Description = myPlainText,
                                	Priority = 'Normal',
                                	Status = 'Inbound Email', 
                                	Subject = mySubject,
                                	whoId = l.Id
                                ));
            // insert the new task
            insert newTask;
            System.debug('New Task Created:' +newTask);
            
                if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) 
                {
                    for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) 
                    {
                        Attachment attachment = new Attachment();
                        // attach to the found record
                        attachment.ParentId = l.Id;
                        attachment.Name = email.binaryAttachments[i].filename;
                        attachment.Body = email.binaryAttachments[i].body;
                        attachment.Description = mySubject;
                        insert attachment;
                    }
                }                
        }
        catch(Exception e)
        {
            System.debug('Exception Issue: ' +e);
        }

        // Return True and exit.
        // True confirms program is complete and no emails 
        // should be sent to the sender of the reply email. 
        result.success = true;
        return result;
    } 
}

Apex Test Class
@isTest(SeeAllData=true)
public class ProcessReplyEmailsTest {
 public static testMethod void testProcessReplyEmails() 
    {        
        Messaging.InboundEmail email = new Messaging.InboundEmail() ;
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

        email.subject = 'Test Subject ';
        email.fromAddress = 'xxx@xxx.com';
        email.plainTextBody = 'Blah Blah Blah';        
          
        ProcessReplyEmails testProcessReplyEmails = new ProcessReplyEmails();
        testProcessReplyEmails.handleInboundEmail(email, env);

             
    }
}

The lines not covered start at newTask.add.

Thanks!
Has anyone run into issues invoking a flow using apex? The logs show that the flow is being started and populated but at the end of the log files it says Internal Salesforce.com Error.

Code to start the flow:
//get the subscriptions
List<Subscription__c> subscriptions = [select id, expiry_date__c, recordTypeId, Renewal_Status__c from subscription__c where id = 'a09S0000006EQ6CIAW'];

//create the flow parameter
Map<String, Object> myMap = new Map<String, Object>();
myMap.put('SelectedSubscriptions', subscriptions);

//launch the flow
Flow.Interview.Subscription_Debug_Flow myFlow = new Flow.Interview.Subscription_Debug_Flow(myMap);
myFlow.start();

I have a custom button which launches the flow from the UI when a subscription has been selected.  This works perfectly and no errors are generated so I know it can't be an issue with the flow itself as it does work.
I'm trying to create a lightning component for a custom object called Comments__c.  Comments__c can be used for Accounts and/or Contacts.

I would like the LC to be dynamic enough where I just have one lightning component for both Accounts and Contacts.  The purpose of the lightning component is to display the comments on the record detail page of either the Account or Contact.  If it's a Contact Record, I would like to display the Account comments as well as the Contact comments.

I'm stuck as to how I can make this lightning component reusable for Contacts.  Here is my code thus far

ListComments.cmp
<aura:component controller = "CommentsController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="newComment" type="Object"/>
    <aura:attribute name="sObjects" type="sObject[]"/>
    <aura:attribute name="CommentList" type="Comment__c[]" />
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    
    <aura:if isTrue="{!not(empty(v.CommentList))}">
    <lightning:card>
        <aura:set attribute="actions">
            <ui:button label="New Comment" press="{!c.createRecord}"/>
        </aura:set>
        <p class="slds-p-horizontal_small slds-text-align_center">
            <aura:iteration  items="{!v.CommentList}" var="com">
                <div class="uiOutputRichText" linkify="true" >
                    <p><ui:outputRichText aura:id="outputRT" value="{!com.Comment__c}" /></p>
                </div>
            </aura:iteration>
        </p>
    </lightning:card>
    </aura:if>
    
    
</aura:component>

CommentsController.apxc
public with sharing class CommentsController {
@AuraEnabled
    public static list<Comment__c> getRelatedList(Id recordId)
    {
        List<Comment__c> commlist = [Select id, active__c, comment__c,contact__c,createdbyid,createddate from Comment__c where Account__c=: recordId AND Active__c = true ORDER BY CreatedDate ASC];
        return commlist;
    }
}

ListCommentsController.js
({
    myAction : function(component, event, helper) 
    {
        var commList = component.get("c.getRelatedList");
        commList.setParams
        ({
            recordId: component.get("v.recordId")
        });
        
        commList.setCallback(this, function(data) 
        {
             component.set("v.CommentList", data.getReturnValue());
        });
        $A.enqueueAction(commList);
    },
    createRecord : function (component, event, helper) {
        var createRecordEvent = $A.get("e.force:createRecord");
        createRecordEvent.setParams({
            "entityApiName": "Comment__c",
            "navigationLocation" : "LOOKUP",
            "defaultFieldValues":{
                "Account__c": component.get("v.recordId")
            },
            "panelOnDestroyCallback": function(event) {
                var urlEvent = $A.get("e.force:navigateToURL");
                urlEvent.setParams({
                    "url": "/lightning/r/Account/"+component.get("v.recordId")+"/view"
                });
                urlEvent.fire();
            }
        });
        createRecordEvent.fire();
        
    }
})


 
I was hoping to get some assistance with code coverage for a particular class.

In my trigger I have:
else if(Trigger.isDelete)
    {
        handler.clearAccountEmails(Trigger.old, Trigger.new, Trigger.oldMap);
    }
Trigger Handler:
public void clearAccountEmails(Contact[] oldContacts, Contact[] updatedContacts, Map<ID, Contact> oldContactsMap)
    {
        List<Account> accounts = new List<Account>();          
        for(Contact c : oldContacts)
        {
            if(c.AccountId != null && c.Primary_Contact__c)
            {
                Account a = new Account(id = c.AccountId);
                if(c.Email != null) a.Primary_Contact_Email_1__c = '';
                if(c.Email != null) a.Customer_Email__c = '';
                if(c.Email_2__c != null) a.Primary_Contact_Email_2__c = '';
                if(c.Servicing_Contact_Method__c  != null) a.Servicing_Contact_Method__c  = ''; 
                accounts.add(a);
            }  
        }
        
        if(!accounts.isEmpty())
        {
            try{
                update accounts;
            }
            catch(exception e){
                System.debug('The following exception has occurred: ' + e.getMessage());
            }
            system.debug(accounts);
        }

I can't seem to get code coverage for the above.  Any assistance would be greatly appreciated.

Thanks!

 
I'm having a bit of trouble writing a test class for the Messaging.InboundEmailHandler class.  I am stuck at 44%.  Any suggestions on how I can achieve 100% code coverage would be greatly appreciated.

Apex Class
// Apex class used to capture reply emails from clients and attach 
// to their lead record
// A task is created against the lead record with the 
// contents of the reply email
// A workflow has also been created to notify the lead
// owner that a new inbound email has been created
global class ProcessReplyEmails implements Messaging.InboundEmailHandler {
    
    Global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope env ) {
        
        // Create an inboundEmailResult object for returning 
        // the result of the email service.
        Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
        
        String mySubject = email.subject;
        String myPlainText = '';
        myPlainText = email.plainTextBody;
        
        // Capture the record ID from the subject line
        String refID = mySubject.right(15);
        System.debug('extract Subject: ' + refID);
        
        // New email task to be created
        Task[] newTask = new Task[0];
        try
        {
        	// Try to lookup the lead record that matches the ID in the subject
        	Lead l = [SELECT Id, Name, Email, Company, Phone, OwnerID FROM Lead WHERE ID = :refID];
            
            newTask.add(new Task(Description = myPlainText,
                                	Priority = 'Normal',
                                	Status = 'Inbound Email', 
                                	Subject = mySubject,
                                	whoId = l.Id
                                ));
            // insert the new task
            insert newTask;
            System.debug('New Task Created:' +newTask);
            
                if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) 
                {
                    for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) 
                    {
                        Attachment attachment = new Attachment();
                        // attach to the found record
                        attachment.ParentId = l.Id;
                        attachment.Name = email.binaryAttachments[i].filename;
                        attachment.Body = email.binaryAttachments[i].body;
                        attachment.Description = mySubject;
                        insert attachment;
                    }
                }                
        }
        catch(Exception e)
        {
            System.debug('Exception Issue: ' +e);
        }

        // Return True and exit.
        // True confirms program is complete and no emails 
        // should be sent to the sender of the reply email. 
        result.success = true;
        return result;
    } 
}

Apex Test Class
@isTest(SeeAllData=true)
public class ProcessReplyEmailsTest {
 public static testMethod void testProcessReplyEmails() 
    {        
        Messaging.InboundEmail email = new Messaging.InboundEmail() ;
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

        email.subject = 'Test Subject ';
        email.fromAddress = 'xxx@xxx.com';
        email.plainTextBody = 'Blah Blah Blah';        
          
        ProcessReplyEmails testProcessReplyEmails = new ProcessReplyEmails();
        testProcessReplyEmails.handleInboundEmail(email, env);

             
    }
}

The lines not covered start at newTask.add.

Thanks!
I want to try to bulkify a headless flow using an apex batch job to call it every hour, but I can't find anything on how to write a test class for a batch that only calls a flow. Has anyone tried to do this? Are there any gotchas you ran into with the flow?
I am trying to use the console integration kit to automatically set the user to online for Live Agent when they start the service cloud console.  Below is my code for a footer component.  It has two ways to set the agent status.  The first is near the bottom of the script where the function to set online is automatically run when the page loads.  The second is a link that the user can click.

There seems to be a timing problem.  The function does run automatically, but it seems to run before the Live Agent component initializes.  I am guessing that my function sets the agent online and then the Live Agent component resets to offline.

I think it is a timing problem because using the link after everything has started does sets the agent online.

Is there an event I can listen for or something else that allows my component to wait until everything is initialized?
<apex:page showHeader="false" sidebar="false">
    <apex:includeScript value="/support/console/29.0/integration.js"/>

    <a href="#" onClick="fnSetAgentState('Online');return false;">Set Agent Status to Online</a> 

    <script type="text/javascript">
        function fnGetAgentState() {
            sforce.console.chat.getAgentState(function(result) {
                if (result.success) {
                    alert('Agent State: ' + result.state);
                } else {
                    alert('getAgentState has failed');
                }
            });
        }
    
        function fnSetAgentState(state) {
            sforce.console.chat.setAgentState(state, function(result) {
                if (result.success) {
                    fnGetAgentState();
                } else {
                    alert('Live Agent: SetAgentState has failed');
                }
            });
        }
        
        fnSetAgentState('Online');
    </script>
</apex:page>