Ads

Tuesday 16 April 2013

SOQL Statements

SOQL statements estimate to a list of sales force Objects, a single sObject, or an Integer for count method queries. For example, we can get details of Account named as ‘Acme’.
SOQL: List accObject = [select id, name from account where name = 'Acme'];
From this list, you can access individual elements.
Code:
if (!accObject.isEmpty()) {
// Execute commands
}
Description:
As above code checks the list of Account object contains value. Following example of code creates a new contact for the first account with the number of employees greater than 10:
Code:
Contact c = new Contact (account = [select name, address from account where NumberofEmployees > 5 limit 1]);
c.FirstName = 'Raees';
c.LastName = 'Ahmed';
insert c;
Description:
Above code inserting contacts where account of employee greater than 5 and limit is 1.
Working with SOQL Aggregate Functions
Aggregate functions in SOQL as same as in SQL, such as SUM () and MAX (), allow you to roll up and summarize your data in the query.
SOQL:
AggregateResult[] groupResult = [SELECT AVG(Amount)aver FROM Opportunity];
Object avgAmount = groupedResults[0].get('aver');
Description:
Note that any query that includes the aggregate function returns its results in an array of AggregateResult objects. AggregateResult is a read-only sObject and the only used for query results.
The following example demonstrates a SOQL query for loop used to mass update records. Suppose you want to change last name of contact across all records of contact:
Code:
public void masUpdate() {
for (List contacts:[Select FirstName, LastName From Contact]) {
if (contacts.FirstName == 'ryan' && contacts.LastName == 'ander') {
contacts.LastName = 'raees';
}//end of if
} //end for
update contacts; //update contact
} // end of class

SOQL Advance Features?

1. Group by feature:
Salesforce Developers are the aware of with “GROUP BY” word in SQL (Stucture Query Language)/SOQL (Salesforce Object Query Language). This key word returns count of records which are selected.
We can put the count to filter the records. My requirement is that if email is duplicates in contact’s record then I need to exclude those records. Following is the code for that, may it will help you too.
SOQL Code:
AggregateResult[] groupedRs = [Select c.Email from Contact c where email =emailed@gmail.com’ group by Email having count(Email)<2];
Description:
As above SOQL checks the email address and group by Email field count is less than 2. So using the above SOQL we could checks how much records are fetching in result set.
2. Salesforce Object initialization feature:
Up till now process to update any sobject was to first query that object using its Ids, and than we used to update that list.
Now if we are having Id of sobject than we need not do any SOQL. For ex-
Code:
Opportunity tempObj = new Opportunity (id = '0063000000Xh92q');
tempObj.name='Test 123';
Update tempObj;
Description:
This above code will update opportunity with Id=’ '0063000000Xh92q'’. Using this approach we can save many SOQL queries.

SOQL Injection?

SOQL injection is a technique by which user effects your application to execute the database methods and you did not intend by passing SOQL statements into your script. Means any user can hack your Database or do fake login in to your secure account without any knowing your password.
This occur in an Apex script whenever your application relies on end user input to the construct a dynamic SOQL statement and you do not handle the input properly. This is the most secure thing you should know about your code of
To prevent SOQL injection, use the escapeSingleQuotes (like ‘\’) method in the Dynamic SOQL. This method adds the escape character (\) to all single quotation marks in a string that is passed in from any user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands.
Code:
public Account[] getAccountInfo() {
    String userInput = Apexpages.currentPage().getParameters().get('nameofAccount');
    Account[] accs = database.query('SELECT name,address,city FROM Account WHERE name = \'' + userInput + '\'');
    return accs;
}
Description:
Above code explain it self user enters Account name and Dynamic SOQL used this name and returns the information about Account.
However if there is hacker user enter Account name like ‘Accoun1’ or ‘xxxxx’ so he can get your secure Account information. We can prevent this write the Class as “with sharing”.

Best Practices of Triggers?

Use Set & Map wherever applicable
Code:
// for every OpportunityLineItem record, add its associated price book entry to a set so there are no duplicates.
trigger oppLineTrigger on OpportunityLineItem (before insert) {
Set pricebookIds = new Set();
for (OpportunityLineItem oli : Trigger.new)
pricebookIds.add(oli.pricebookentryid);
// Query the PricebookEntries for their associated product color and place the results in a map of price book entery.
Map entries = new Map( [select product2.color__c from pricebookentry where id in :pbeIds]);
// Now use the map to set the appropriate color on every OpportunityLineItem processed by the trigger.
for (OpportunityLineItem oli : Trigger.new)
oli.color__c = entries.get(oli.pricebookEntryId).product2.color__c;
}
Correlating Records with Query Results in Bulk Triggers
• Use the Trigger.newMap and Trigger.oldMap ID-to-sObject maps to correlate records with query results
trigger oppTrigger on Opportunity (before delete) {
for (Quote__c q : [select opportunity__c from quote__c where opportunity__c in :Trigger.oldMap.keySet()])
{
Trigger.oldMap.get(q.opportunity__c).addError('Cannot delete opportunity with a quote');
}
}

Triggers and Order of Execution?

Triggers and Order of Execution
  When user Save record with insert, update or upsert statement in salesforce.com.
1. Client Side Execution:
  • JavaScript validation
  • Dependent pick list
2. Server side Execution:
  • Loads the original record from the database or initializes the record for an upsert statement.
  • Loads the new record field values from the request and overwrites the old values. If the request came from a standard UI edit page, Salesforce runs system validation to check the record for:
    * Compliance with layout-specific rules
    * Required values at the layout level and field-definition level
    * Valid field formats
    * Maximum field length
   Salesforce does not perform system validation in this step when the request comes from other sources, such as an Apex application or a Web services API call.
  • Executes all before triggers.
  • Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any user-defined validation rules. The only system validation that Salesforce does not run a second time (when the request comes from a standard UI edit page) is the enforcement of layout-specific rules.
  • Saves the record to the database, but does not commit yet.
  • Executes all after triggers.
  • Executes assignment rules.
  • Executes auto-response rules.
      ·   Executes workflow rules.
·   If there are workflow field updates, updates the record again.
  • If the record was updated with workflow field updates, fires before and after triggers one more time (and only one more time), in addition to standard validations. Custom validation rules are not run again.
  • Executes escalation rules.
  • If the record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Parent record goes through save procedure.
  • If the parent record is updated, and a grand-parent record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Grand-parent record goes through save procedure.
  • Executes Criteria Based Sharing evaluation.
  • Commits all DML operations to the database.
  • Executes post-commit logic, such as sending email.
*Note: During a recursive save, Salesforce skips steps 7 through 14.
Additional Considerations

Additional Considerations:
Please note the following when working with triggers:

    * When Enable Validation and Triggers from Lead Convert is selected, if the lead conversion creates an opportunity and the opportunity has Apex before triggers associated with it, the triggers run immediately after the opportunity is created, before the opportunity contact role is created. For more information, see “Customizing Lead Settings” in the Salesforce online help.

   * If you are using before triggers to set Stage and Forecast Category for an opportunity record, the behavior is as follows:
          o If you set Stage and Forecast Category, the opportunity record contains those exact values.
          o If you set Stage but not Forecast Category, the Forecast Category value on the opportunity record defaults to the one associated with trigger Stage.
          o If you reset Stage to a value specified in an API call or incoming from the user interface, the Forecast Category value should also come from the API call or user interface. If no value for Forecast Category is specified and the incoming Stage is different than the trigger Stage, the Forecast Category defaults to the one associated with trigger Stage. If the trigger Stage and incoming Stage are the same, the Forecast Category is not defaulted.

   * If you are cloning an opportunity with products, the following events occur in order:
         1. The parent opportunity is saved according to the list of events shown above.
         2. The opportunity products are saved according to the list of events shown above.
    

Handling Governor Limits through Trigger?

1. Bulkify your code:
Bad Code
trigger accTrggr on Account (before insert, before update) {
//This only handles the first record in the Trigger.new collection
//But if more than one Account initiated this trigger, those additional records
//will not be processed
Account acct = Trigger.new[0];
acct.Description = acct.Name + ':' + acct.BillingState;
}
Correct Code
trigger accTrggr on Account (before insert, before update) {
List accountNames = new List{};
//Loop through all records in the Trigger.new collection
for(Account a: Trigger.new) {
//Concatenate the Name and billingState into the Description field a.Description = a.Name + ':' + a.BillingState;
}}
2. Avoid SOQL Queries inside FOR Loops
Move SOQL queries outside FOR loop
Bad Code
trigger accountTestTrggr on Account (before insert, before update) {
for(Account a: Trigger.new) {
List contacts = [select id, salutation, firstname, lastname, email from Contact where accountId = :a.Id];
for(Contact c: contacts){
c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
update c;
} } }
Good Code
trigger accountTestTrggr on Account (before insert, before update) {
List accountsWithContacts = [select id, name, (select id, salutation, description, firstname, lastname, email from Contacts) from Account where Id IN :Trigger.newMap.keySet()];
List contactsToUpdate = new List{};
for(Account a: accountsWithContacts){
for(Contact c: a.Contacts){
c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname; contactsToUpdate.add(c);
} }
update contactsToUpdate;
}
3. Bulkify your Helper Methods
  • Similar to the Previous One.
  • All Helper Methods should also be handling Bulk records.
  • For Eg: A inside a method should receive a bulk set of inputs, process in bulk and return the List of Records.
4. Using Collections, Streamlining Queries, and Efficient For Loops
Bad Code
trigger accountTrigger on Account (before delete, before insert, before update) {
//This code inefficiently queries the Opportunity object in two seperate queries
List opptysClosedLost = [select id, name, closedate, stagename from Opportunity where accountId IN :Trigger.newMap.keySet() and StageName='Closed - Lost'];
List opptysClosedWon = [select id, name, closedate, stagename from Opportunity where accountId IN :Trigger.newMap.keySet() and StageName='Closed - Won'];
for(Account a : Trigger.new){
//This code inefficiently has two inner FOR loops
//Redundantly processes the List of Opportunity Lost
for(Opportunity o: opptysClosedLost){
if(o.accountid == a.id)
System.debug('Do more logic here...'); }
//Redundantly processes the List of Opportunity Won
for(Opportunity o: opptysClosedWon){
if(o.accountid == a.id) System.debug('Do more logic here...'); } } }
Good Code
trigger accountTrigger on Account (before delete, before insert, before update) {
/*This code queries all related Closed Lost & Closed Won oppor in a single query. */
List accountWithOpptys = [select id, name, (select id, name, closedate, stagename from Opportunities where accountId IN :Trigger.newMap.keySet() and (StageName='Closed - Lost' or StageName = 'Closed - Won')) from Account where Id IN :Trigger.newMap.keySet()];
//Loop through Accounts only once
for(Account a : accountWithOpptys){
//Loop through related Opportunities only once
for(Opportunity o: a.Opportunities){
if(o.StageName == 'Closed - Won'){
System.debug('Opportunity Closed Won...do some more logic here...');
}else if(o.StageName =='Closed - Lost'){
System.debug('Opportunity Closed Lost...do some more logic here...');
} } } }
5. Streamlining Multiple Triggers on the Same Object
  • Many Triggers for a single Object
  • Order of execution cant be defined
  • All Triggers executing in a single transaction will SHARE the governor limits.
  • Add appropriate conditions for trigger executions
  • Handling of Governor Limits across all the triggers
  • If possible, join the triggers
6. Querying Large Data Sets
Bad Code
//A runtime exception is thrown if this query returns 1001 or more records.
Account [] accts = [SELECT id FROM account];
Good Code
// Use this format for efficiency if you are executing DML statements
// within the for loop
for (List accts : [SELECT id, name FROM account WHERE name LIKE 'Acme']) {
// Your code here
update accts;
}
7. Other Best Practices
  • Use of the Limits Apex Methods to Avoid Hitting Governor Limits
  • Limits.getLimitQueries()
  • Limits.getLimitDmlRows()
  • Enable Apex Governor Limit Warning Emails
  • Write Test Methods to Verify Large Datasets

SFDC INTERVIEW QUSETIONS

50 Salesforce.com Interview Questions

Salesforce.com is currently one of most sought after technology. If you are an experienced Salesforce.com guy, you are lucky. Having said that, even if you are someone who has recently started out working on Salesforce.com, don't worry, there are enough resources available on the internet to help you start.

I will be posting some of the learning techniques and how I prepared for Salesforce.com soon in my blog.

However, here are some of the most common interview questions I have come across for a developer/administrator role.

Questions:
1. How many users have you supported. 
2. What are permission sets and how do they differ from profiles. 
3. When will you use profile and permission sets together. 
4. Difference between roles and profiles.
5. What are controllers. 
6. What are extensions. 
7. Difference between controllers and extensions.
8. What is a standard controller, custom controller. Difference between the two. 
9. When you override a button by specifying a VF page, what is a necessary condition for the VF page to be available.
Ans - The VF page should have a standard controller listed for that object. Else, the VF page will not be available to override a button. 
10. Minimum number of queries required to query for 2 level, 3 level relationships. 
11. How will you avoid recursive triggers. 
12. How to bulkify triggers. 
13. Understand basic SOQL and Apex limits. 
14. What is with sharing and without sharing class.
15. How can sharing be done using Apex. 
16. Explain the trigger handler pattern. 
17. List few components which cannot be deployed using force.com IDE or change sets. 
18. What deployment methods have you used. List advantages and disadvantages of each. 
19. How will you load data for a child object. 
20. Difference between a look up and master-detail relationship.
21. Explain, the way you will query child from parent and parent from child
22. What are sharing rules, when do you used sharing rules. 
23. Explain lead to opportunity conversion.
24. What are record types. Why are the record types used. 
25. When is page layout assignment used. 
26. Can 1 user be assigned multiple profiles, if yes how, if not, what is the work around.
27. How many types of salesforce licenses are there. What are the limits. 
28. Which license will I use if users will only use 1 custom application.
29. How can I create developer, full sandbox.
30. In how many days can one refresh a full sandbox.
31. What is batch apex. Why do we use batch apex. 
32. What is @future method.
33. What are test classes, what is the test coverage you need to move a code into production. 
34. Can I directly change code in salesforce production org. 
35. How do I log a case with salesforce. 
36. How can I change owner for multiple cases at once (example - from Rob to John)
37. Difference between a workflow rule and approval process. 
38. What is the order of execution of workflow rules, validation rules, triggers.
39. Explain Salesforce.com security implementation with respect to Profiles, Roles and Hierarchy, Sharing rules, OWD(org wide default settings). Also, specify which is the most restrictive security setting. 
40. What are custom report types. 
41. What are different types of reports you can create. 
42. What is Trigger.old and Trigger.New
43. What is ApexPages.addMessage
44. How is a pdf generated using visual force page.
45. How can I redirect user to a page after processing is completed in the controller/extension.
46. What are custom settings. 
47. What are Action Support, Action Function and Action Poller used for. 
48. What is rerender attribute used for. 
49. What is package.xml
50. How can one read parameter values through the URL in Apex. 

Monday 15 April 2013

Trigger for field update in Salesforce?

The below Apex code is used to update a field(Comments__c) in Member__c Object,

where Marital__Status and Comments__c are fields n Member__c object.

Code:

trigger commentsUpdate on Member__c (before Insert,before update) 

     for(Member__c member : Trigger.new)  
     {      
         if(member.Marital_Status__c != '')    
         {      
             member.Comments__c = member.Marital_Status__c;    
         }       
         else   
         {      
             member.Comments__c = 'No comments';    
         }       
     }  
}

Difference between trigger.new and trigger.old in salesforce?

Trigger.new : Returns a list of the new versions of the sObject records. Note that this sObject list is only available in insert and update triggers, and the records can only be modified in before triggers.

Trigger.old : Returns a list of the old versions of the sObject records. Note that this sObject list is only available in update and delete triggers.

For more info visit the below link

http://www.salesforce.com/us/developer/docs/apexco​de/Content/apex_triggers_context_variables.htm

Trigger.isInsert() and trigger.isUpdate() in salesforce?

trigger memberInviteNotify on Member__c (after insert,after update)
{
    for(Member__c member:trigger.New)
    {
        String[] toAddresses = new String[] {member.E_Mail_Id__c};
        String messageBody;
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(toAddresses);
    
        //Email invitation
        if(trigger.isInsert)
        {
            mail.setSubject('Welcome to Sweet 16');
            messageBody = 'Hi ' + member.Name + ', Welcome to Sweet 16';
            mail.setHtmlBody(messageBody);
        }
        //Email notification
        if(trigger.isUpdate)
        {
            mail.setSubject('Updates in your details');
            messageBody = 'Hi ' + member.Name + ', Changes have been made to your details. Contact administrator if you are not responisble.';
            mail.setHtmlBody(messageBody);
        }
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

Trigger to Warn for Duplicate Attachment Names and Contents in Salesforce?

The below trigger is used to warn the users, if the Filename or Content of  an attachment already exists.

Trigger:

/*    Trigger to Warn for Duplicate Attachment Names and Contents    */
trigger DuplicateAttachment on Attachment (before insert)
{
for(Attachment attachmnt:trigger.New)
{
String sql = 'SELECT Name,Description FROM Attachment';
List<Attachment> attach = Database.Query(sql);

for(Attachment temp:attach)
{
if(temp.Name == attachmnt.Name)
{
attachmnt.Name.addError('Duplicate Name. Filename already exists.');
}
if(temp.Description == attachmnt.Description)
{
String str = 'Similar content already exists in ' + temp.Name;
attachmnt.Description.addError(str);
}
}
}
}

trigger.isInsert and trigger.isUpdate?

trigger.isInsert is true when a new record is created and inserted.

trigger.isUpdate is true when an existing record is modified.

Example:

trigger memberInviteNotify on Member__c (after insert,after update)
{

        if(trigger.isInsert)
        {
        // When a new record is created and inserted, the flow will come here
        ............................
        ............................
        ............................ 
        }
        
        if(trigger.isUpdate)
        {

        // When an existing record is modified, the flow will come here
        ............................
        ............................
        ............................
        }

}

Recursive triggers in Salesforce?

You want to write a trigger that creates a new record as part of its processing logic; however, that record may then cause another trigger to fire, which in turn causes another to fire, and so on. You don't know how to stop that recursion.

     Use a static variable in an Apex class to avoid an infinite loop. Static variables are local to the context of a Web request (or test method during a call to runTests()), so all triggers that fire as a result of a user's action have access to it.

Example:
     Suppose there is a scenario where in one trigger perform update operation, which results in invocation of second trigger and the update operation in second trigger acts as triggering criteria for trigger one.

Solution:

Class:

public class Utility
{
    public static boolean isFutureUpdate;
}


Trigger:

trigger updateSomething on Account (after insert, after update) 
{
 
    /*  This trigger performs its logic when the call is not from @future */
    if(Utility.isFutureUpdate != true)
    {
 
        Set<Id> idsToProcess = new Se<Id>();
 
        for(Account acct : trigger.new)
        {
            if(acct.NumberOfEmployees > 500)
            {
                idsToProcess.add(acct.Id);
            }
        }
 
        /* Sending Ids to @future method for processing */
        futureMethods.processLargeAccounts(idsToProcess);
 
    }
}

Class:

public class FutureMethods
{
 
    @future
    public static void processLargeAccounts(Set<Id> acctIDs)
    {
 
        List<Account> acctsToUpdate = new List<Account>();
 
        /* isFutureUpdate is set to true to avoid recursion */
        Utility.isFutureUpdate = true;
        
        update acctsToUpdate;
    }
}

When to use triggers in Salesforce?

Triggers are used to perform immediate actions based on previous action.
Example: field update.
     A trigger is Apex code that executes before or after specific Data Manipulation Language (DML) events occur, such as before object records are inserted into the database, or after records have been deleted.
Syntax:
trigger triggerName on ObjectName (trigger_events)
{
    /*------------
    code_block
    -------------*/
}
where trigger_events can be a comma-separated list of one or more of the following events:
  1. before insert
  2. before update
  3. before delete
  4. after insert
  5. after update
  6. after delete
  7. after undelete

Trigger to create child object after checking some condition in parent record?

Sample Trigger:

trigger ageInterest on Member__c (after insert, after update)
{
    for(Member__c mem:trigger.New)
    {
        if(mem.Age__c == 18)
        {
            Interest__c it = new Interest__c(Name = 'Ghost Movies',Member__c = mem.ID);
            insert it;
        }
    }
}


Here Member__c is Parent object and Interest__c is child object.

Executing Trigger based on field value in Salesforce?

Sample Trigger:

 trigger test on Member__c (after insert)
{
    List<Case> cases = new List<Case>();

    for(Member__c mem:Trigger.new)
    {
        if(
mem.Comments__c != null || mem.Comments__c != '')
        {
                Case newCase = new Case(subject='Material',Status='New',Origin='Web');           
                insert newCase;

        }
    }

}

Welcome message and update notification trigger in Salesforce?

Sample Code:

trigger memberInviteNotify on Member__c (after insert,after update)
{
    for(Member__c member:trigger.New)
    {
        String[] toAddresses = new String[] {member.E_Mail_Id__c};
        String messageBody;
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(toAddresses);
       
        //Email invitation
        if(trigger.isInsert)
        {
            mail.setSubject('Welcome to Sweet 16 Siebel Batch');
            messageBody = '<html><body>Hi ' + member.Name + ',<br>Welcome to Sweet 16.<br><br><b>Regards,</b><br>Magulan D</body></html>';
            mail.setHtmlBody(messageBody);  
        }
       
        //Email notification
        if(trigger.isUpdate)
        {
            mail.setSubject('Updates in your details');
            messageBody = '<html><body>Hi ' + member.Name + ',<br>Changes have been made to your details. <br><br>Contact administrator if you are not responisble.</body></html>';
            mail.setHtmlBody(messageBody);
        }
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

Trigger.old example in Salesforce?

Sample Trigger:

trigger userNamEmaiil on User (before insert, before update)
{
    if(trigger.isInsert)
    {
        for(User u : trigger.new)
        {
            if(u.name != u.Email)
            {
                u.addError('Username and Email should be same');
            }          
        }
    }
    else if(trigger.isUpdate)
    {   
        for(User o : trigger.old)
        {
            for(User n : trigger.new)
            {
                if(o.email != n.Email)
                {
                    n.addError('Email address cannot be changed');
                }  
            }
        }
    }
}


Output:

Triggers in Salesforce

Apex can be invoked through the use of triggers. A trigger is Apex code that executes before or after the following types of operations:

• insert
• update
• delete
• merge
• upsert
• undelete

For example, you can have a trigger run before an object's records are inserted into the database, after records have been deleted, or even after a record is restored from the Recycle Bin.

You can define triggers for any top-level standard object, such as a Contact or an Account, but not for standard child objects, such as a ContactRole.

• For case comments, click Your Name > Setup > Customize > Cases > Case Comments > Triggers.
• For email messages, click Your Name > Setup > Customize > Cases > Email Messages > Triggers.

Triggers can be divided into two types:

• Before triggers can be used to update or validate record values before they are saved to the database.
• After triggers can be used to access field values that are set by the database (such as a record's Id or lastUpdated field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue.

Code coverage for Task Trigger?

Trigger:

trigger deletetask on Task (before delete)
    {
    if(System.Trigger.IsDelete)
        {
        for (Task t : trigger.old)
            if (t.check__c == 1)
                {
                t.addError('Error: You cannot delete a Task when it is marked complete.');
                }
        }         
}


Test Class:

@isTest
public class testClass
{
    static testmethod void test()
    {
        Task t = new Task(Type = 'Email',check__c = 0);
        insert t;
        delete t;
    }
}


Output:


Record is read-only error in Apex Trigger?

Field update cannot be done after the record has been Updated/Saved.

So, use after insert or after update as the trigger events.

Cheers!!!

Trigger to update the Date field one day less than to next year?

trigger dateUpdate on Pincode__c (before insert, before update)
{
    for(Pincode__c p : trigger.New)
    {
        p.X1st_Anniversary__c = p.Evaluation_Date__c.addDays(364);
        p.X6th_Anniversary__c = p.Evaluation_Date__c.addDays(2184);
    }
}

When to use before and after trigger in Salesforce?

Before Trigger:
In case of validation check in the same object.
Insert or update the same object.

After Trigger: 
Insert/Update related object, not the same object.
Notification email.
We cannot use After trigger, if we want to update a record because it causes read only error. This is because after inserting or updating, we cannot update a record.

How to call Apex class in trigger in Salesforce?


trigger sample on Account (before insert)
{
    for(Account a : trigger.New)
    {
        sampleRest s = new sampleRest();
    }
}



Sample Apex Class:

public class sampleRest
{
     ......................
      ......................
      ......................
      ......................
}

Difference between triggers and workflow rules in Salesforce


Triggers
Work flow rules
Trigger can work across objects.
Workflow Rules will be helpful to update the same object or master object in custom master-detail relationships.
Coding is required.
Coding is not required.
Trigger works before and after some actions.
Workflows work only after some actions.

GROUP BY in SOQL

SELECT Count(Name), OwnerId From Opportunity Where OwnerId in ('005A0000002U5TcIAK',
'005A0000002U5U1IAK', '005A0000002U5ULIA0') and StageName in ('Active - Low Probability','Active - Med. Probability','Active - High Probability','Active - Commit') GROUP BY OwnerId