• Jeff Hutchinson 17
  • NEWBIE
  • 0 Points
  • Member since 2017

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 8
    Replies
We are using Process Builder to call an InvocableMethod when the stage changes on an opportunity. The method creates a case and sends an email to its owner. When the opportunity is updated via the API, after the case is created the assignment rules run and reassign the case to a queue. This causes an error when the next block of code tries to send an email to the queue. I can update the opportunity via the UI without any issues.
...
// Create Case
        for (Opportunity opps : oppsList) {
            Case c = new Case(BusinessHoursId = '01mf20000008TQr', AccountId = opps.AccountId,
                    Case_Reason__c = 'Refer to Dentist', Description = opps.Account.Name + ' - Refer to Dentist', Destination__c = 'Support',
                    Origin = 'In-House', Status = 'Closed', Subject = opps.Account.Name + ' - Refer to Dentist', Type = 'Patient Updates',
                    OwnerId = accountMap.get(opps.AccountId).Patient_Care_Contact__c,
                    ContactId = accIdToContactMap.get(opps.AccountId).Id);
            casesToInsert.add(c);
        }

        System.debug('casesToInsert: ' + casesToInsert);
        insert casesToInsert;
        List<Case> insertedCases = [SELECT Id, AccountId, ContactId, OwnerId, Account.Patient_Care_Contact__c FROM Case WHERE Id IN :casesToInsert];
        System.debug('insertedCases: ' + insertedCases);

        // Email Pt
        EmailTemplate et = [Select Id from EmailTemplate where DeveloperName = 'Refer_to_Dentist'];
        OrgWideEmailAddress owea = [SELECT Id FROM OrgWideEmailAddress WHERE Address = 'support@email.byteme.com' LIMIT 1];
        List<Messaging.SingleEmailMessage> emailToSend = new List<Messaging.SingleEmailMessage>();
        for (Case c : insertedCases) {
            String[] recipients = new String[]{c.ContactId, c.OwnerId, 'mtamayo@byteme.com'};
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setTargetObjectId(c.ContactId);
            email.setWhatId(c.Id);
            email.setTemplateId(et.Id);
            email.setToAddresses(recipients);
            email.setOrgWideEmailAddressId(owea.Id);
            emailToSend.add(email);
        }
Messaging.sendEmail(emailToSend);
As I understand it, Assignment Rules should not be running here. I realize there are changes I could make to the Assignment Rules to prevent the reassignment but I would prefer for everything to work as intended rather than use a work-around. I have an open case with Salesforce but because we're not a Premier Service member they haven't given much help.

Can someone please confirm that the assignment rules should not be running here, or if they should be, tell me how I can disable them?
Is it possible to create a custom pre-chat form for snap-ins chat without using Lightning Components, Aura Components, or Visualforce? Ideally, this would be done in HTML similar to how the pre-chat is customized using liveagent.prechat methods similar to the following.
First Name: <input type="text" name="liveagent.prechat:firstName" id='firstName' /><br /> 
Last Name: <input type="text" name="liveagent.prechat:lastName" /><br />
Email Address: <input type="text" name="liveagent.prechat:leadEmail" /><br />
While HTML is ideal, examples for any of the above methods would be appreciated. 
I have successfully implemented Live Agent with a pre-chat page on an external website. Currently, a Case is created and attached to every chat transcript. I would like to be able to search for a person account based on the pre-chat information to attach to the case and person account and if a person account is not found search for a lead and if a lead is not found then create one.

An alternative solution would be to add a field where the chat visitor can indicate if they already have an account and then search person accounts if they do and leads if they do not. If possible, I would like to avoid this solution because someone will always enter the wrong information.
I am trying to use a PendingServiceRouting After Insert Trigger to manually create an AgentWork object to assign cases through Omni-Channel but it appears the trigger is not firing. I am able to create cases via Email-to-Case and query the PendingServiceRouting object, so I know it is being created. I am also able to call my code from Anonymous Apex, passing in the PendingServiceRouting object I created and it executes as expected.

Can anyone confirm that After Insert triggers can be used with PendingServiceRouting objects and/or offer some advice on how to proceed?
 
trigger OnPendingServiceRoutingTrigger on PendingServiceRouting (after insert) {

    if (trigger.isAfter && trigger.isInsert) {
        System.debug('After Insert PendingServiceRouting Trigger');
        PendingServiceRoutingTriggerHandler.afterInsert(trigger.newMap);
    }
}
public class PendingServiceRoutingTriggerHandler {

    public static void afterInsert (Map<Id, PendingServiceRouting> NewPsr) {

    ...

    }
}


 
Hi all,
I am trying to create a table within a table. Each row in both tables has an add and delete button to add and remove rows. The buttons for the outer table and the button to add rows to the inner table function correctly. The problem is that I am unable to delete rows from the inner table. I basically used the same code for both the inside and outside tables so I don't understand why one works and the other does not. From what I can tell the index number (deleteButtonNumber) for the delete commandLinks is always equal to the highest index of the last group in the inner table. My code is as follows.

Visualforce Page:
<apex:page id="AddItems" showHeader="true" sidebar="true" standardController="Formulary__c" extensions="AddItemsExtension">
    <apex:messages />
    <apex:form id="form">
        <apex:pageBlock title="Add Items Page" id="block">

            <apex:pageBlockButtons>
                <!-- Continue Button -->
                <apex:commandButton value="Continue" action="{!continueButton}"/>
                <!-- Cancel Button -->
                <apex:commandButton value="Cancel" action="{!cancelButton}"/>
                <!-- Add Group Button -->
                <apex:commandButton value="Add Group" action="{!addNewGroupToList}"/>
            </apex:pageBlockButtons>


            <apex:variable value="{!0}" var="groupNumber"/>
            <apex:pageBlockSection collapsible="false" columns="1">
                <apex:pageBlockTable value="{!groupList}" var="groupRecord" columnsWidth="10%,10%,10%,70%">
                    <apex:column headerValue="Group" width="100px">
                        {!'Group ' + TEXT(groupNumber + 1) }<br/>
                    </apex:column>

                    <!-- Add Product Link -->
                    <apex:column>
                        <apex:commandLink value="Add product to group" action="{!addProductButton}">
                            <apex:param value="{!groupNumber}" assignTo="{!buttonNumber}" name="buttonNumber"/>
                        </apex:commandLink>
                    </apex:column>

                    <!-- Delete Link -->
                    <apex:column>
                        <apex:commandLink value="Delete This Group" action="{!deleteGroupButton}">
                            <apex:param value="{!groupNumber}" assignTo="{!buttonNumber}" name="buttonNumber"/>
                        </apex:commandLink>
                    </apex:column>

                    <!-- Item List -->
                    <apex:variable value="{!0}" var="productNumber"/>
                    <apex:column headerValue="Item List">
                        <apex:pageBlockTable value="{!groupRecord.prods}" var="product">
                            <apex:column>
                                <apex:commandLink value="Delete Product" action="{!deleteProductButton}">
                                    <apex:param value="{!productNumber}" assignTo="{!deleteButtonNumber}" name="deleteButtonNumber"/>
                                    <apex:param value="{!groupNumber}" assignTo="{!buttonNumber}" name="buttonNumber"/>
                                </apex:commandLink>
                            </apex:column>
                            <apex:column>
                                <apex:outputText value="{!product.Product_Name__c}"/> <br/>
                            </apex:column>
                            <apex:variable var="productNumber" value="{!productNumber + 1}"/>
                        </apex:pageBlockTable>
                    <apex:variable var="groupNumber" value="{!groupNumber + 1}"/>
                    </apex:column>

                </apex:pageBlockTable>
            </apex:pageBlockSection>

        </apex:pageBlock>
    </apex:form>
</apex:page>
Apex Extension:
public class AddItemsExtension {

    ApexPages.standardController controller = null;
    public Integer groupNumber {get; set;}
    public Integer productNumber {get; set;}
    public List<DiscountGroup> groupList {get; set;}
    public List<Formulary__c> productList {get; set;}
    public Integer buttonNumber {get; set;}
    public Integer deleteButtonNumber {get{ return deleteButtonNumber;} set {deleteButtonNumber = value; System.debug('deleteButtonNumber set to ' + deleteButtonNumber);}}
    public String searchTerm {get; set;}
    public List<Formulary__c> searchResults {get; set;}
    public String formList {get; set;}

    public AddItemsExtension(ApexPages.StandardController controller) {
        this.controller = controller;
        groupList = new List<AddItemsExtension.DiscountGroup>();
        addNewGroupToList();
    }

    // Continue Button OnClick method
    public PageReference continueButton() {
        PageReference nextPage = Page.ProductQuery;
        nextPage.setRedirect(false);

        return nextPage;
    }

    // Cancel Button OnClick method
    public PageReference cancelButton() {
        return controller.cancel();
    }

    // Back Button OnClick method
    public PageReference backButton() {
        searchTerm = '';
        PageReference lastPage = Page.AddItems;
        lastPage.setRedirect(false);
        return lastPage;
    }

    // Add Group Button OnClick method
    public void addNewGroupToList() {
        DiscountGroup newGroup = new DiscountGroup();
        newGroup.prods = new List<Formulary__c>();
        newGroup.requireAll = true;
        newGroup.quantity = 1;
        groupList.add(newGroup);
    }

    public void deleteGroupButton() {
        groupList.remove(buttonNumber);
    }

    public void deleteProductButton() {
        System.debug('buttonNumber: ' + buttonNumber +
                    '\ndeleteButtonNumber: ' + deleteButtonNumber +
                    '\ngroupNumber: ' + groupNumber);
        groupList[buttonNumber].prods.remove(deleteButtonNumber);
    }

    // Add Product Button OnClick method
    public PageReference AddProductButton() {
        searchTerm = '';
        PageReference nextPage = Page.ProductQuery;
        nextPage.setRedirect(false);
        return nextPage;
    }

    public void search() {
        searchResults = new List<Formulary__c>();
        String temp = '%' + searchTerm + '%';
        searchResults = [SELECT Id, Product_Name__c FROM Formulary__c WHERE Product_Name__c LIKE :temp AND Formulary_Status__c != 'Discontinued' ORDER BY Product_Name__c ASC];
    }

    public List<SelectOption> getformChoices() {
        List<SelectOption> options = new List<SelectOption>();
        for (Formulary__c form : searchResults) {
            options.add(new SelectOption(form.Id, form.Product_Name__c));
        }
        return options;
    }

    public PageReference addItem() {
        Formulary__c tempForm = [SELECT Id, Product_Name__c FROM Formulary__c WHERE Id = :formList];
        groupList[buttonNumber].prods.add(tempForm);
        PageReference lastPage = Page.AddItems;
        lastPage.setRedirect(false);
        return lastPage;

    }

    public class DiscountGroup {
        public List<Formulary__c> prods {get; set;}
        public boolean requireAll {get; set;}
        public Integer quantity {get; set;}
    }
}
Any help is appreciated.
Hi everyone,

     I have this trigger on contact and I have no idea how to write the test class for this. Any help will be greatly appreciated. 

Thank you in advance!
public class contactHandlerClass {
     public static boolean contactRecursion =false; // to avoid the "maximum trigger depth exceeded" error


    public static void getRecentTaskInformation(List<Contact> contacts) {
       
        System.debug('print the list' + contacts);
 //Tasks     
        List<Contact> contactsWithLastTasks = [
            SELECT Id, Last_Activity_Subject__c, Last_Activity_Date__c,Contact_Task_Date__c,	Most_Recent_Contact_Task_Subject__c,
                Last_Activity_Name__c , Last_Activity_Assigned_to__c ,
                Last_Activity_TypeOfInteraction__c , Name, (
                    SELECT Subject, ActivityDate, Owner.Name,Task.WhoId,
                        Type_of_Interaction__c
                    FROM Tasks
                    ORDER BY ActivityDate DESC 
                    LIMIT 1
                )
            FROM Contact WHERE Id IN :contacts
        ];
      
        for (Contact c : contactsWithLastTasks) {
            if (!c.tasks.isEmpty()) {
                Task lastTask = c.tasks[0];
                System.debug('print Tasks' + lastTask);

                c.Most_Recent_Contact_Task_Subject__c = lastTask.Subject;
                c.Contact_Task_Date__c = lastTask.ActivityDate;
                // may be create field and set it text "Task" to identify if it is Task or Event
                
                System.debug('Print contacts list one by one?'+ contactsWithLastTasks);
                System.debug('Field one?'+ c.Most_Recent_Contact_Task_Subject__c);
                System.debug('Field two?'+ c.Contact_Task_Date__c);
        
            }
        }
        If(!contactsWithLastTasks.isEmpty()){
        Update contactsWithLastTasks;
        }
 //Events
        List<Contact> contactsWithLastEvents = [
            SELECT Id, Last_Activity_Subject__c, Last_Activity_Date__c,Contact_Task_Date__c,	Most_Recent_Contact_Task_Subject__c,
                Last_Activity_Name__c , Last_Activity_Assigned_to__c ,
                Last_Activity_TypeOfInteraction__c , Name, (
                    SELECT Subject, StartDateTime
                    FROM Events
                    ORDER BY ActivityDate DESC 
                    LIMIT 1
                )
            FROM Contact WHERE Id IN :contacts
        ];
      
        for (Contact c : contactsWithLastEvents) {
            if (!c.events.isEmpty()) {
                Event lastEvent = c.events[0];
                System.debug('print Tasks' + lastEvent);

                c.Most_Recent_Contact_Task_Subject__c = lastEvent.Subject;
                //c.Contact_Task_Date__c = lastEvent.;
                // may be create field and set it text "Task" to identify if it is Task or Event
                
                System.debug('Print contacts list one by one?'+ contactsWithLastEvents);
                System.debug('Field one?'+ c.Most_Recent_Contact_Task_Subject__c);
                System.debug('Field two?'+ c.Contact_Task_Date__c);
        
            }
        }
        If(!contactsWithLastEvents.isEmpty()){
        Update contactsWithLastEvents;
        }
    }

}


 
Is it possible to create a custom pre-chat form for snap-ins chat without using Lightning Components, Aura Components, or Visualforce? Ideally, this would be done in HTML similar to how the pre-chat is customized using liveagent.prechat methods similar to the following.
First Name: <input type="text" name="liveagent.prechat:firstName" id='firstName' /><br /> 
Last Name: <input type="text" name="liveagent.prechat:lastName" /><br />
Email Address: <input type="text" name="liveagent.prechat:leadEmail" /><br />
While HTML is ideal, examples for any of the above methods would be appreciated. 

Hi,

I am trying to make a field(s) Required in page layout ?
But the option is greyed out .. FLS is not read only..
Any ideas .. ?

Thanks,

Raghu

I am trying to use a PendingServiceRouting After Insert Trigger to manually create an AgentWork object to assign cases through Omni-Channel but it appears the trigger is not firing. I am able to create cases via Email-to-Case and query the PendingServiceRouting object, so I know it is being created. I am also able to call my code from Anonymous Apex, passing in the PendingServiceRouting object I created and it executes as expected.

Can anyone confirm that After Insert triggers can be used with PendingServiceRouting objects and/or offer some advice on how to proceed?
 
trigger OnPendingServiceRoutingTrigger on PendingServiceRouting (after insert) {

    if (trigger.isAfter && trigger.isInsert) {
        System.debug('After Insert PendingServiceRouting Trigger');
        PendingServiceRoutingTriggerHandler.afterInsert(trigger.newMap);
    }
}
public class PendingServiceRoutingTriggerHandler {

    public static void afterInsert (Map<Id, PendingServiceRouting> NewPsr) {

    ...

    }
}