Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I've created a trigger that shares a case with two related users on the record. I wasn't aware that once the case assignment rules were triggered it would remove the CaseShare records. http://help.salesforce.com/apex/HTViewSolution?id=000079752&language=en_US

Can someone provide me with some guidance on how to move my code to a class so I can insert the records in a future method? I've only written triggers and have never put code in a class although I realize it's a best practice. Right now, this is the only trigger on the case object.

Here is my code. Thank you in advance.

trigger CaseShares2 on Case (after insert) {

Id recordTypeId = [Select Id From RecordType Where SObjectType = 'Case' And DeveloperName='Sales'].Id;
if(trigger.isInsert){

    List<CaseShare> caseShrs  = new List<CaseShare>();


    CaseShare managerShare;
    CaseShare aeShare;

    for(Case c : trigger.new){
        if(c.RecordTypeID == recordTypeID && c.AE__c != NULL && c.Manager__c != NULL){

            managerShare = new CaseShare();
            aeShare = new CaseShare();

            managerShare.CaseID = c.Id;
            aeShare.CaseID = c.Id;

            managerShare.UserOrGroupId = c.AE__c;
            aeShare.UserOrGroupId = c.Manager__c;


            managerShare.CaseAccessLevel = 'edit';
            aeShare.CaseAccessLevel = 'edit';

            caseShrs.add(managerShare);
            caseShrs.add(aeShare);

        }

    }

}
    Database.SaveResult[] lsr = Database.insert(caseShrs,false);

}

share|improve this question
add comment

1 Answer 1

up vote 4 down vote accepted

When it comes down to it, an Apex class is very similar to a trigger syntax wise. You can take the body of the trigger an put it in a method in an Apex class. Then call it from the trigger, passing just the required context information from the trigger.

Try and keep the body of the trigger to a minimum and get all the work done in the apex class. Ideally you will only have one trigger per object type. This makes it easier to track what is happening and in what order.

To move into an asynchronous future context you will need to pass the Case Ids as primitive data types and then use SOQL to get the required fields. See also: Future Annotation

Minimal Trigger

trigger CaseShares2 on Case (after insert) {
    if(trigger.isInsert) {
        CaseTriggerHandler cth = new CaseTriggerHandler();
        ctc.handleCaseInsert(Trigger.new);
    }
}

Apex class

public class CaseTriggerHandler {

    public void handleCaseInsert(List<Case> triggerNew) {
        // Convert to primitive data type for future method parameters
        List<string> caseIds = new List<string>();
        for(Case c : triggerNew) {
            caseIds.add(c.Id);
        }
        handleCaseInsertFuture(caseIds);
    }

    @future
    static void handleCaseInsertFuture(List<string> caseIds) {

        List<Case> triggerNew = [Select Id, RecordTypeID, AE__c, Manager__c from Case where ID in :caseIds];

        Id recordTypeId = [Select Id From RecordType Where SObjectType = 'Case' And DeveloperName='Sales'].Id;

        List<CaseShare> caseShrs  = new List<CaseShare>();

        for(Case c : triggerNew) {
            if(c.RecordTypeID == recordTypeID && c.AE__c != NULL && c.Manager__c != NULL) {

                CaseShare managerShare = new CaseShare();
                CaseShare aeShare = new CaseShare();

                managerShare.CaseID = c.Id;
                aeShare.CaseID = c.Id;

                managerShare.UserOrGroupId = c.AE__c;
                aeShare.UserOrGroupId = c.Manager__c;

                managerShare.CaseAccessLevel = 'edit';
                aeShare.CaseAccessLevel = 'edit';

                caseShrs.add(managerShare);
                caseShrs.add(aeShare);
            }
        }
    }

    if(caseShrs.size() > 0) {
        Database.SaveResult[] lsr = Database.insert(caseShrs, false);
    }

}

See also:

share|improve this answer
    
Thanks! To clarify, in order to call a future method from this trigger I would need to send over a list of primitives or IDs? Then I would query those IDs back and create case shares records? Is that the best way? Thank you –  Coffee Jun 27 at 8:09
    
@Coffee Correct, you need to pass primitive data types to the future method and then query for the required case fields. I've expanded the example. –  Daniel Ballinger Jun 27 at 8:57
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.