+ Start a Discussion
KennyShenKennyShen 

Automatically Associate Entitlement to Case

Hi,

 

I'm working on a trigger to call a class which assigns an Entitlement on Cases according to the Priority and Account on the case. The trigger and class both work for cases created internally, but won't work for customers through the customer portal. Below are the triggers and class involved. The customer portal profiles have Read access for the Entitlement object. Any help would be greatly appreciated!

 

trigger AssignEntitlementTrigger on Case (before insert){

    Case[] cases = trigger.new;
    List<Id> CaseAccounts = new List<Id>();
    List<Entitlement> EntitlementToAdd = new List <Entitlement>();
    Case cA = cases[0];
      if(cases[0].Priority == 'Critical'){
            EntitlementToAdd = [Select Id From Entitlement 
                                    Where AccountId = :cA.AccountId and 
                                    Entitlement.Support_process__c = 'Critical' 
                  limit 1];
//                trigger.new[0].Action_needed_by__c = 'BigMachines';
        }
      else if(cases[0].Priority != 'Critical'){            
            if(cases[0].Support_Product__c == 'Premium'){
                   
              EntitlementToAdd = [Select Id From Entitlement 
                                    Where AccountId = :cA.AccountId and Entitlement.Support_Process__c = 'Premier'
                                    limit 1];
//                   trigger.new[0].Action_needed_by__c = 'Customer';
            }
        else {               
            EntitlementToAdd = [Select Id From Entitlement
                                Where AccountId = :cA.AccountId and Entitlement.Support_Process__c = 'Standard'
                                limit 1];
//         trigger.new[0].Action_needed_by__c = 'User';
        }
       }
    
    if(EntitlementToAdd.isEmpty() == false){
        AssignEntitlementOnCase.assignEntitlement(cases, EntitlementToAdd);
        }
//        trigger.new[0].Action_needed_by__c = '3rd Party';
}

 

 

public class AssignEntitlementOnCase{

    public static void assignEntitlement(List<Case> cases, List<Entitlement> EntitlementToAdd) {
        List<Case> CasesToUpdate = [Select Id, EntitlementId From Case cases Where EntitlementId = null limit 3];
        if(CasesToUpdate.isEmpty() == false){
            for(Case c : cases){
            c.EntitlementId = EntitlementToAdd[0].Id;
            }
        }
    }
}

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Jerun JoseJerun Jose

It seems like you have modified your code since you last post it.

 

Anyway, change your code snippet as follows.

 

list<ID> accountIDs = new list<ID>();
for(case c : trigger.new){
	if(c.AccountId != null)
		accountIDs.add(c.accountID);
}

if(!accountIDs.isEmpty())
	CaseAccounts = [Select Id, Name From Account Where Id = :accountIDs];

 If caseAccounts is a list of accounts, then use the snippet as it.

If it is actually a list of IDs, then you can use the accountIDs variable instead,

All Answers

Tim BarsottiTim Barsotti

Hi Kenny,

 

You should review how to bulkify your trigger as this code will not hold up against bulk operations: http://wiki.developerforce.com/page/Best_Practice%3A_Bulkify_Your_Code 

 

I would throw a system.debug(trigger.new) at the top of your trigger and then turn on debugging for the portal user. Most likely, not all fields that you are referencing are populated when created via portal. Assignment rules, which set priority for email to case, etc, are processed after the insertion triggers. Does the case have an accountId when submitted by the portal user or is this set by a post insertion process? 

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm

 

Hope this helps get you in the right direction.

KennyShenKennyShen

Hi Tim,

 

Thanks for the information! I'm going through the code to properly bulkify it now, but I'm new to this and unfamiliar with debugging. I've added the system.debug at the top, but what do you mean by "turn debugging on for the portal user"? 

 

In our portal, the Contact name is defaulted on the case create page, and then the AccountId is set based on the contact after insertion. However, I can't find what's actually setting it. It doesn't look like there's a trigger or workflow field update, and yet the required field is being populated automatically. This question sounds like a long shot, but is there any way to address the order of execution stuff without knowing what's setting the Account on Case creation?

 

 

Thanks,

Kenny

Tim BarsottiTim Barsotti

If you look at a case that was created by the portal user, you can reference the "Created By" field to know which user this was created by. Then from setup you can go to 'Debug Logs' and enable logging for that user.

 

If the values you need are not there when the case is 'inserted' you my need a 'before update' trigger to process this correctly. The before update would require more logic as you would not want to add entitlements for each update to a case. Find out if it is there on insert (via debugging) and go from there. 

Jerun JoseJerun Jose

Cases created by customer portal users will have the contact as the customer portal user and the account as the customer account.

 

I believe this happens as somewhat of a ghost process. Even if you change the contact/account for that case in your before triggers/ DML update, the system will just reset these fields back to their initial values until you change the record owner.

 

More to the point here, you should be able to identify the value of accountID field for the case in the before insert/ before update events itself to perform your logic.

KennyShenKennyShen

Thank for the info guys!

 

I've got my trigger working properly now, but it still doesn't stand up to bulk operations. I'm coming across the "Too many SOQL Queries: 101" error when I test it by inserting 100 new cases through Data Loader.

 

I've initialized my lists and performed all the necessary SOQL queries outside of my For Loops, except for one:

 

    for(case c : trigger.new){
    if(c.AccountId != null){
    Account acct = [Select Id, Name From Account Where Id = :c.AccountId];
    CaseAccounts.add(acct);
    }

which appears to be what's causing the error, but I can't seem to figure a way of getting the list CaseAccounts filled, without it being inside a for loop. 

 

 

 

 

Jerun JoseJerun Jose

It seems like you have modified your code since you last post it.

 

Anyway, change your code snippet as follows.

 

list<ID> accountIDs = new list<ID>();
for(case c : trigger.new){
	if(c.AccountId != null)
		accountIDs.add(c.accountID);
}

if(!accountIDs.isEmpty())
	CaseAccounts = [Select Id, Name From Account Where Id = :accountIDs];

 If caseAccounts is a list of accounts, then use the snippet as it.

If it is actually a list of IDs, then you can use the accountIDs variable instead,

This was selected as the best answer
KennyShenKennyShen

Yes, major revisions were definitely in order. Thanks for the quick reply and working code!