Parse CSV using Apex

public List<List<String>> parseCSV(String contents,Boolean skipHeaders) 
{  
     List<List<String>> allFields = new List<List<String>>();  
     // replace instances where a double quote begins a field containing a comma  
     // in this case you get a double quote followed by a doubled double quote  
     // do this for beginning and end of a field  

     contents = contents.replaceAll(‘,”””‘,’,”DBLQT’).replaceall(‘”””,’,’DBLQT”,’);  

     // now replace all remaining double quotes – we do this so that we can reconstruct  
     // fields with commas inside assuming they begin and end with a double quote  

     contents = contents.replaceAll(‘””‘,’DBLQT’);  

     // we are not attempting to handle fields with a newline inside of them  
     // so, split on newline to get the spreadsheet rows  

     List<String> lines = new List<String>();  

     try 
     {  
         lines = contents.split(‘\n’);  
     } 
     catch (System.ListException e) 
     {  
         System.debug(‘Limits exceeded?’ + e.getMessage());  
     }  

     Integer num = 0;  

     for(String line : lines)
{  

         // check for blank CSV lines (only commas)  

         if (line.replaceAll(‘,’,”).trim().length() == 0) break;             
         List<String> fields = line.split(‘,’);      

         List<String> cleanFields = new List<String>();  

         String compositeField;  

         Boolean makeCompositeField = false;  

         for(String field : fields) 
         {  

             if (field.startsWith(‘”‘) && field.endsWith(‘”‘)) 
             {  
                 cleanFields.add(field.replaceAll(‘DBLQT’,'”‘));  
             } else if (field.startsWith(‘”‘)) 
             {  
                 makeCompositeField = true;  
                 compositeField = field;  
             } 
             else if (field.endsWith(‘”‘)) 
             {  
                 compositeField += ‘,’ + field;  
                 cleanFields.add(compositeField.replaceAll(‘DBLQT’,'”‘));  
                 makeCompositeField = false;  

             } 
             else if (makeCompositeField) 
             {  
                 compositeField +=  ‘,’ + field;  
             } 
             else 
             {  
                 cleanFields.add(field.replaceAll(‘DBLQT’,'”‘));  
             }  
         }            
         allFields.add(cleanFields);  

     }  

     if (skipHeaders) allFields.remove(0);  

     return allFields;         



/* Method to parse List<List<String>> to sObject */
public list<sObject> csvTosObject(List<List<String>> parsedCSV, string objectType)
    {
        Schema.sObjectType objectDef = Schema.getGlobalDescribe().get(objectType).getDescribe().getSObjectType();
        System.debug(‘Object Definition –> ‘ + objectDef);
        
        list<sObject> objects = new list<sObject>();
        list<string> headers = new list<string>();
        
        for(list<string> row : parsedCSV)
        {
            for(string col : row)
            {
                headers.add(col);
            }
            break;
        }
        System.debug(‘Headers –> ‘ + headers);
        integer rowNumber = 0;
        for(list<string> row : parsedCSV)
        {
            if(rowNumber == 0)
            {
                rowNumber++;
                continue;
            }
            else
            {
                sObject thisObj = objectDef.newSobject();
                integer colIndex = 0;
                for(string col : row)
                {                   
                    string headerName = headers[colIndex].trim();
                    system.debug(‘========================= Column Name ‘ + headerName);
                    if(headerName.length() > 0)
                    {                  
                        try
                        {                       
                        if(col.contains(‘/’))
                        {
                        Date tempDate;
                        String[] tempStr = col.split(‘/’);
                        Integer d = Integer.valueOf(tempStr[0]);
                        Integer m = Integer.valueOf(tempStr[1]);
                        Integer y = Integer.valueOf(tempStr[2]);
                        tempDate = Date.newInstance(y,m,d);
                        thisObj.put(headerName,tempDate);
                        }
                        else
                        {
                        thisObj.put(headerName,col.trim());
                        }                            
                        }
                        catch(exception e)
                        {
                            system.debug(‘============== Invalid field specified in header ‘ + headerName);                           
                        }
                        colIndex++;
                    }
                } 
                objects.add(thisObj);
                rowNumber++;
            }       
        }        
        System.debug(‘Object Data –> ‘ + objects);
        return objects;
    }
}

Trigger on candidate to validate address

trigger CandidateAddressValidation on Candidate__c (after insert, after update, before update) {
    // We only call the async method if this trigger was fired from the UI, not from a batch API call
    if (Trigger.new.size() == 1){
        // If this is an insert we always do the async call
        if (Trigger.isInsert) {
            //AddressValidator.validateAddress(Trigger.new[0].id);
        }
        
        // If this is an update, we check the AsyncValidationFlag to see if this address has been validated already
        // If already validated (flag==true) then we don’t do the callout again
        // Only do the callout when the asyncvalidationflag is false
        if (Trigger.isUpdate){
            if (Trigger.isBefore) {
                // in the before we just check to see if the streets, city, or state have changed (NOTE: not zip since that is changed by the async method)
                // if one of them has changed, we change the flag to be false
                if ((Trigger.new[0].Street_Address_1__c != Trigger.old[0].Street_Address_1__c) ||
                    (Trigger.new[0].Street_Address_2__c != Trigger.old[0].Street_Address_2__c) ||
                    (Trigger.new[0].City__c != Trigger.old[0].City__c) ||
                    (Trigger.new[0].State_Province__c != Trigger.old[0].State_Province__c)) {
                    // if one of the above fields changed then reset the flag so the record gets picked up by the async call
                    Trigger.new[0].AsyncValidationFlag__c = false;    
                }
                System.debug(‘\ncandidate=’ + Trigger.new[0] + ‘\n’);
            } else {
                if (!Trigger.new[0].asyncvalidationflag__c){
                    //AddressValidator.validateAddress(Trigger.new[0].id);
                }
            }
        }
    }
}

Trigger on lead to insert lead in campaign

trigger InsertLeadinCampaign on Lead (after insert, after update) {
    
    list<Campaign> Camp = new list<Campaign>();
    camp = [select id, GAC_Campaign_Tag__c from Campaign   lIMIT 50000];
    list<CampaignMember> lstCampMem = new list<CampaignMember>();
    
    if(Trigger.isInsert && Trigger.isAfter )
    {
        for(lead l: Trigger.new)
        {
            for(Campaign cm : camp)
            {  
                CampaignMember cc = new CampaignMember();
                if(cm.GAC_Campaign_Tag__c == l.cloudamp__GAC_Campaign__c)
                {
                    cc.CampaignId=cm.Id;
                    cc.LeadId=l.Id;
                    lstCampMem.add(cc);
                }
            }   
        }    
    
      if(lstCampMem.size()>0){
          insert lstCampMem;
          
      }

    }
    if(Trigger.isUpdate && Trigger.isAfter){
        list<CampaignMember> cml = new list<CampaignMember>();
        list<CampaignMember> oldCM= new list<CampaignMember>();
        if(camp.size()>0){
              oldCM = [select CampaignId, LeadId, Lead.Email from CampaignMember where CampaignId In:camp];
        }
         Map<id,CampaignMember> cmMap = new Map<id,CampaignMember>();
         for(CampaignMember cm2 : oldCM){
              cmMap.put(cm2.LeadId, cm2);
         }
         system.debug(‘——-cmMap——–‘+cmMap);
        for(lead l: Trigger.new)
        {
            system.debug(‘——–trigger.oldmap.get(l.id).cloudamp__GAC_Campaign__c———‘+trigger.oldmap.get(l.id).cloudamp__GAC_Campaign__c);
            system.debug(‘——–trigger.newmap.get(l.id).cloudamp__GAC_Campaign__c———‘+l.cloudamp__GAC_Campaign__c);
            if(trigger.oldmap.get(l.id).cloudamp__GAC_Campaign__c != trigger.newmap.get(l.id).cloudamp__GAC_Campaign__c)
              {
                 for(Campaign cm : camp)
                 {  
                    CampaignMember cc = new CampaignMember();
                    if(cm.GAC_Campaign_Tag__c == l.cloudamp__GAC_Campaign__c)
                    {
                        
                            cc.CampaignId=cm.Id;
                            cc.LeadId=l.Id;
                            cml.add(cc);
                        
                    }
                }   
            }
        }    
    
          if(cml.size()>0){
              insert cml;
          }
    }
}

Securing Your Apex Code

APEX SECURITY
Apex Class Security Overview
Available in: Unlimited, Developer, Enterprise, and Database.com Editions
You can specify which users can execute methods in a particular top-level Apex class based on their profile or an associated permission set. These permissions only apply to Apex class methods, such as Web service methods, or any method used in a custom Visualforce controller or controller extension applied to a Visualforce page. Triggers always fire on trigger events (such as insert or update), regardless of a user’s permissions.
Note: If you have installed a managed package in your organization, you can set security only for the Apex classes in that package that are declared as global, or for classes that contain methods declared as webService.
If users have the “Author Apex” permission, they can access all Apex classes in the associated organization, regardless of the security setting for individual classes.
Permission for an Apex class is checked at the top level only. For example, if class A calls class B, and a user profile has access only to class A but not class B, the user can still execute the code in class A. Likewise, if a Visualforce page uses a custom component with an associated controller, security is only checked for the controller associated with the page. The controller associated with the custom component executes regardless of permissions.
You can set Apex class security via:
• The Apex class list page
• An Apex class detail page
• Permission sets

 

 

Tips on Building Formulas

• Default value formulas for a type of record can only reference fields for that type of record. However, formula fields and formulas for approvals or rules, such as workflow, validation, assignment, auto-response, or escalation, for a type of record can reference fields for that type of record as well as any records that are related through a lookup or master-detail relationship. For example, a formula for a validation rule on opportunities can reference merge fields for accounts and campaigns as well as opportunities, and a formula field on accounts can reference fields for cases.
• Formula fields that a user can see may reference fields that are hidden or read only using field-level security. If the formula field contains sensitive information, use field-level security to hide it.
• You can add activity formula fields to task and event page layouts. Note that a task-related formula field on an event page layout may not be useful. Likewise, event-related formula fields on task page layouts may not be useful.
• To determine if a record is a task or event, use the IsTask merge field. For example:
IF(IsTask, “This is a task”, “This is an event”)
• To reference the unique identifier for your Salesforce organization in a formula, insert the $Organization.Id merge field. This merge field can display anywhere formula fields can except in reports.
• Some merge fields display as radio buttons but function like picklist fields when referenced in a formula.
Use the values “Read,” “Edit,” and “None” in a formula when referencing:
◊ $UserRole.CaseAccessForAccountOwner
◊ $UserRole.OpportunityAccessForAccountOwner
◊ CaseAccessLevel (on Territory)
◊ OpportunityAccessLevel (on Territory)
Use the values “Read,” “Edit,” and “All” in a formula when referencing:
◊ AccountAccessLevel (on Territory)
• If you create a contacts formula field that references account merge fields, that field can be included in contact page layouts but should not be included in person accounts page layouts. The formula field will display a value of #Error on the person accounts page.

Restrictions
• The following limits apply to formula fields:
◊ Character limit—Formula fields can contain up to 3,900 characters, including spaces, return characters, and comments. If your formula requires more characters, create separate formula fields and reference them in another formula field.
Note: The maximum number of displayed characters after an evaluation of a formula expression is 1,300
characters.
◊ Save size limit—Formula fields cannot exceed 4,000 bytes when saved. The save size differs from the number of characters if you use multi-byte characters in your formula.
◊ Compile size limit—Formula fields cannot exceed 5,000 bytes when compiled. The compile size is the size of the formula (in bytes) including all of the fields, values, and formulas it references. There is no direct correlation between the compile size and the character limit. Some functions, such as TEXT, DATEVALUE, DATETIMEVALUE, and DATE significantly increase the compile size.
• Long text area, encrypted, and Description fields are not available for use in formulas.
• The value of a field cannot depend on another formula that references it.
• Fields referenced in formulas cannot be deleted. Remove the field from the formula before deleting it.
• Task Due Date is not available for use in formulas.
• Campaign statistic fields cannot be referenced in formulas for field updates, approval processes, workflow rules, or validation rules, but can be referenced in custom formula fields.
Working with Date and Date/Time Fields
• Dates and times are always calculated using the user’s time zone.
• Date and date/time fields cannot be used interchangeably. The name alone may not indicate if a field is a date or date/time.
For example, Created Date and Last Modified Date are date/time fields whereas Last Activity Date is a
date field. Use the DATEVALUE function to convert a date/time field into a date field.
Note: The Created Date and Last Modified Date fields display only the date, not the date and time.
• Use addition and subtraction operators with date or date/time fields to calculate duration. For example, subtract a date from another date to calculate the number of days between the two. Likewise, you can subtract the date/time from another date/time to get the number of days between the two in the form of a number. See NOW or TODAY for suggested use.
• Use addition and subtraction operators with numbers to return another date or date/time. For example, {!CreatedDate} + 5 calculates the date and time five days after a record’s created date. Note that the expression returns the same data type as the one given; a date field plus or minus a number returns a date, and a date/time field plus or minus a number returns a date/time.
• When calculating dates using fractions, Salesforce ignores any numbers beyond the decimal. For example:
TODAY() + 0.7 is the same as TODAY() + 0, which is today’s date TODAY() + 1.7 is the same asTODAY() + 1, which is tomorrow’s date TODAY() + (-1.8) is the same as TODAY() + (-1), which is yesterday’s date
• To calculate the value of two fractions first, group them within parentheses. For example:
TODAY() + 0.5 + 0.5 is the same as TODAY() + 0 + 0, which is today’s date TODAY() + (0.5+0.5) is the same as TODAY() + 1, which is tomorrow’s date
• Years cannot be zero and must be between -4713 and 9999.
Working with Text Fields
• Before using the HYPERLINK function, consider the differences between hyperlinks and custom links.
◊ Hyperlink formula fields are just like other custom fields that you can display in list views and reports.
◊ Custom links display on detail pages in a predefined section; hyperlink formula fields can display on a detail page wherever you specify.
◊ Using custom links, you can specify display properties such as window position and opening in a separate popup position; hyperlink formula fields open in a new browser window by default or you can specify a different target window or frame.
◊ Your formulas can reference custom links. Before deleting a custom link, make sure it is not referenced in a formula field.
◊ Hyperlink formula fields that contain relative URLs to Salesforce pages, such as /rpt/reportwizard.jsp, can be added to list views, reports, and related lists. However, use a complete URL, including the server name and https://, in your hyperlink formula before adding it to a search layout. Note that formula fields are not available in search result layouts.
• Before using the HYPERLINK function, consider these:
◊ Hyperlink formula fields open in a new browser window by default or you can specify a different target window or frame.
◊ Hyperlink formula fields that contain relative URLs to Salesforce pages can be added to list views and related lists.
However, use a complete URL, including the server name and https://, in your hyperlink formula before adding it to a search layout. Note that formula fields are not available in search result layouts.
• To insert text in your formula field, surround the text with quotation marks. For example, to display “CASE: 123,” use this formula “CASE: “& CaseNumber__c.
• Use the backslash (\) character before a quote or backslash to insert it as a literal value in your output. For example, “Trouble\\Case \”Ticket\”: ” in your formula displays Trouble\Case “Ticket”: on detail pages.
Working with Number Fields
• Use the decimal version of a percent when working with percent fields in formulas. For example, IF(Probability =1…) for 100% probability or IF(Probability =0.9…) for 90% probability.
• Reference auto-number fields as text fields in formulas.
• The output of your formula must be less than 19 digits.
• Formulas can contain a mix of numbers, percents, and currencies as in this example: AnnualRevenue /
NumberOfEmployees.
• Salesforce uses the round half up tie-breaking rule for numbers in formula fields. For example, 12.345 becomes 12.35 and −12.345 becomes −12.35.
 

Referencing Record Types in Formulas
Reference record types in formulas if you want different workflow rules, validation rules, and lookup filters to apply to different record types. For example, you can:
• Create a workflow rule on accounts that emails different teams depending on the account record type the user selects when creating the account.
• Create a validation rule on opportunities that allows only members of the North American sales team to save opportunities with the Domestic record type.
When possible, use RecordTypeId instead of RecordType.Name to reference a specific record type. While
RecordType.Name makes a formula more readable, you must update the formula if the name of the record type changes, whereas the ID of a record type never changes. Also, RecordType.Name requires a cross-object reference to the record type, while RecordTypeId does not. However, if you are deploying formulas across organizations (for example, between sandbox and production), use RecordType.Name because IDs are not the same across organizations.
Avoid using $RecordType in formulas, except in default value formulas. Instead, use the RecordType merge field (for example, Account.RecordType.Name) or the RecordTypeId field on the object.
Working with Picklists and Multi-Select Picklists
• You can use special picklist fields in your formulas, such as IsEscalated for cases and IsWon for opportunities.
• Picklist fields can only be used in the following functions:
◊ ISPICKVAL—Compares the value of a picklist to a single value.
◊ CASE—Compares the value of a picklist to multiple values.
◊ TEXT—Converts a picklist value into a text value so that you can work with the value in functions that support text value, such as CONTAINS. (Only available in formula fields, validation rules, and workflow field updates.)
• The TEXT function always returns picklist values in your organization’s master language, not the language of the current user.
• Multi-select picklist fields can only be used in the following functions:
◊ INCLUDES
◊ ISBLANK
◊ ISNULL
◊ ISCHANGED (Only in assignment rules, validation rules, workflow field updates, and workflow rules in which the evaluation criteria is set to Evaluate the rule when a record is: created, and every time it’s edited)
◊ PRIORVALUE (Only in assignment rules, validation rules, workflow field updates, and workflow rules in which the evaluation criteria is set to Evaluate the rule when a record is: created, and every time it’s edited).

Visualforce Report On forecast object

<apex:page controller=”ForecastIndividual_Controller” >

<apex:form >
<table align=”center” width=”100%”>
<tr><td align=”center”><font size=”4″><b>Sales Forecasts</b></font></td></tr>
<tr><td align=”center”><hr/></td></tr>
<tr>
<td align=”center”><b>Select User :</b>&nbsp;&nbsp;
<apex:selectList size=”1″ value=”{!selectedValue}”>
<apex:actionsupport action=”{!Userinfo}” event=”onchange” rerender=”uInfo” status=”Status”/>
<apex:selectOptions value=”{!Items}” />
</apex:selectList>
<apex:actionstatus id=”Status” starttext=”  Loading…”></apex:actionstatus>
<br/><br/>
</td>
</tr>
</table>
</apex:form>

<apex:outputpanel id=”uInfo”>
<table width=”100%”>
<tr>
<td style=”border: 1px solid black;”>
<table width=”100%” height=”100%” border=”0″ cellpadding=”10″ cellspacing=”10″ >
<tr>

<td bgcolor=”#D8D8D8″><b>SalesPerson</b></td>
<td><apex:outputText value=”{!u1.name}”/></td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>Address</b></td>
<td><apex:outputText value=”{!u1.Street}”/></td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>Phone</b></td>
<td><apex:outputText value=”{!u1.Phone}”/></td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>Cell</b></td>
<td><apex:outputText value=”{!u1.MobilePhone}”/></td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>Email</b></td>
<td><apex:outputText value=”{!u1.Email}”/></td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>Salesforce Login</b></td>
<td><apex:outputText value=”{!u1.Username}”/></td>
</tr>
</table>
</td>
<td width=”2%”></td>
<td style=”border: 1px solid black;”>
<table width=”100%” height=”100%”  cellspacing=”10″ cellpadding=”5″>
<tr>
<td width=”70%”></td>
<td bgcolor=”#D8D8D8″ width=”15%” align=”center”><b>Forecast</b></td>
<td bgcolor=”#D8D8D8″ width=”15%” align=”center”><b>Actual</b></td>
</tr>
<apex:repeat value=”{!tr}” var=”tar”>
<tr>
<td bgcolor=”#D8D8D8″><b>{!tar.Month_Year__c}&nbsp;Dealer</b></td>
<td align=”center”>{!tar.Target__c}</td>
<td align=”center”>{!tar.Opportunities__r.size}</td>
</tr>
<tr>
<td bgcolor=”#D8D8D8″><b>{!tar.Month_Year__c}&nbsp;Revenue</b></td>
<td align=”center”>{!tar.Target_Amount__c}</td>
<td align=”center”>{!strmap[tar]}</td>
</tr>
</apex:repeat>
</table>
</td>
<td width=”2%”></td>
<td style=”border: 1px solid black;”>
<apex:include pageName=”compareAgentreport”/>
</td>
</tr>
</table>

</apex:outputpanel>
</apex:page>

public class ForecastIndividual_Controller {
public Map<string, list<Target__c>> usmap{get;set;}
public Map<string, Decimal> strmap{get;set;}
public list<Target__c> tr {get;set;}
private list<User> u;
public User u1{get;set;}
public string selectedValue{get;set;}
public string uid{get;set;}
public string param;

public ForecastIndividual_Controller ()
{
tr = new list<Target__c>();

usmap = new Map<String, list<Target__c>>();
strmap = new Map<string, Decimal>();
uid = ApexPages.currentPage().getParameters().get(‘uid’);
u = new list<User>();
tr = [Select t.Year__c, t.User__c, t.Target__c,t.User__r.Name, t.Target_Amount__c, t.SystemModstamp, t.OwnerId, t.Name, t.Month__c, t.Month_Year__c,
(Select Id, Name,Amount From Opportunities__r)From Target__c t];
u = [Select u.Street, u.State, u.PostalCode, u.Phone, u.Name, u.MobilePhone,u.Username, u.LastName, u.FirstName, u.Fax, u.Email, u.City From User u where IsActive=true and Profile.name<>’newCarSellOffSite Profile’];
for(Target__c t : tr)
{
if(!usmap.containskey(t.User__r.Name))
{
usmap.put(t.User__r.Name,new Target__c[]{t});
}
else
{
usmap.get(t.User__r.Name).add(t);
}

Decimal Amount = 0;
for(Opportunity o:t.Opportunities__r)
{
If(o.Amount!=null)
{
Amount += o.Amount;
}
}
strmap.put(t.Id,Amount);
}
param = ApexPages.currentpage().getparameters().get(‘id’);
If(param!=null)
{
selectedValue = param;
u1= new User();
u1= [Select u.Street, u.State, u.PostalCode, u.Phone,u.Username, u.Name, u.MobilePhone, u.LastName, u.FirstName, u.Fax, u.Email, u.City From User u where id=:selectedValue limit 1];
tr = [Select t.Year__c, t.User__c, t.Target__c,t.User__r.Name, t.Target_Amount__c, t.SystemModstamp, t.OwnerId, t.Name, t.Month__c, t.Month_Year__c,
(Select Id, Name,Amount From Opportunities__r)From Target__c t where User__c =:selectedValue];
}
}
public List<SelectOption> getItems()
{
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption(”,’–Select User–‘));
for(User usr : u){
options.add(new SelectOption(usr.id,Usr.Name));
}
return options;
}
public PageReference Userinfo()
{
system.debug(‘———selectedValue——‘+selectedValue);
PageReference reference=new PageReference(‘/apex/ForecastIndividual?id=’+selectedValue).setRedirect(true);
return reference;
}
}

Trigger on Campaign member to count campaign history

trigger CountCampaign on CampaignMember (after insert,before delete) {
    set<Id> cid = new set<Id>();
    Map<id,Account> amap = new Map<id,Account>();
    list<Account> updateacclist = new list<Account>();
    for(CampaignMember cm : trigger.isDelete?trigger.old:trigger.new)
    {
        cid.add(cm.ContactId);
    }
    
    list<Account> acclist =[Select a.PersonContactId, Campaign_count__c,a.Id From Account a where PersonContactId in: cid];
    
     
        for(Account a : acclist)
        {
            amap.put(a.PersonContactId,a);
        }
    
    system.debug(‘amapppppppp—–‘+amap);

    
    for(CampaignMember cm :trigger.isDelete?trigger.old:trigger.new)
    {
        if(amap.containskey(cm.ContactId))
        {
            Account ac = new Account();
            ac=amap.get(cm.ContactId);
            if(trigger.isInsert)
            {
              if(ac.Campaign_count__c==null)
              {
                ac.Campaign_count__c=0;
              }
            ac.Campaign_count__c += 1;
            }
            if(trigger.isDelete){
            ac.Campaign_count__c-=1;
            }
            updateacclist.add(ac);
            system.debug(‘———-‘+ac);
        }
    }
    
    
    
    
    system.debug(‘———-‘+updateacclist);
    
    if(updateacclist.size()>0)
    {
        update updateacclist;
    }

}

Trigger on Task to add contact roles.

trigger aiTask on Task (after insert)
{
   public static final String CONTACT_ROLE_TBD = ‘TBD’;

   // Get a unique list of Account IDs.
   // Map Tasks with both Account and Contact by Contact ID.
   set<Id> accountIds = new set<Id>();
   map<Id, Task> taskMap = new map<Id, Task>();
   for (Task t : system.trigger.new)
   {
      // Accounts have a prefix of 001.
      if (t.WhatId != null &&
          String.valueOf(t.WhatId).substring(0, 3) == ‘001’)
      {
         accountIds.add(t.WhatId);
         // Contacts have a prefix of 003.
         if (t.WhoId != null &&
             String.valueOf(t.WhoId).substring(0, 3) == ‘003’)
         {
            // Map Tasks by Contact where the Task has
            // both an Account and a Contact.
            taskMap.put(t.WhoId, t);
         }
      }
   }
   if (accountIds.size() == 0) return;

   // Get a list of Contact Roles for these Accounts.
   list<AccountContactRole> roleList =
      [SELECT Id, AccountId, ContactId, Role
         FROM AccountContactRole
        WHERE AccountId IN :accountIds];
   
   // Map Contact Roles by Account AND by Contact.
   // This is a map of maps for ease of indexing.
   // The outside map is indexed by Account and
   // the inside map is indexed by Contact.
   map<Id, map<Id, AccountContactRole>> roleMap =
      new map<Id, map<Id, AccountContactRole>>();
   map<Id, AccountContactRole> localMap =
      new map<Id, AccountContactRole>();
   AccountContactRole localRole;
   for (AccountContactRole acr : roleList)
   {
      // First, get the inner map.
      localMap = roleMap.get(acr.AccountId);
      // If it isn’t there, create it.
      if (localMap == null || localMap.size() == 0)
      {
         localMap = new map<Id, AccountContactRole>();
      }
      // Second, get the inner ACR record.
      localRole = localMap.get(acr.ContactId);
      // If it isn’t there, add it.
      if (localRole == null)
      {
         localMap.put(acr.contactId, acr);
      }
      // Add the inner map back to the outer map.  
      roleMap.put(acr.AccountId, localMap);
   }
   
   // Loop over the Tasks that we picked out above.
   list<AccountContactRole> insertRecords =
      new list<AccountContactRole>();
   AccountContactRole acr;
   for (Task t : taskMap.values())
   {
      // First get the outer map based on the Account ID.
      localMap = roleMap.get(t.WhatId);
      if (localMap != null)
      {
         // Next look for a matching ACR record
         // based on the Contact ID.
         localRole = localMap.get(t.WhoId);
         // Not found? Let’s add it!
         if (localRole == null)
         {
            acr = new AccountContactRole(
               AccountId = t.WhatId,
               ContactId = t.WhoId,
               Role = CONTACT_ROLE_TBD);
            insertRecords.add(acr);
            // Put this back into the map for future
            // processing on this transaction.
            localMap.put(t.WhoId, acr);
            roleMap.put(t.AccountId, localMap);
         }
      }
      else
      {
         // There aren’t any ACR records for this Account yet,
         // so there is nothing in the roleMap yet.
         acr = new AccountContactRole(
            AccountId = t.WhatId,
            ContactId = t.WhoId,
            Role = CONTACT_ROLE_TBD);
         insertRecords.add(acr);
         // Put this back into the map for future
         // processing on this transaction.
         localMap.put(t.WhoId, acr);
         roleMap.put(t.AccountId, localMap);
      }
   }
   if (insertRecords.size() > 0) insert insertRecords;
}

Trigger on lead to prevent duplicate leads

trigger leadDuplicatePreventer on Lead (before insert, before update) {
        Map<String,lead> leadmap = new Map<String,lead>();
        for(lead l: system.trigger.new)
        {
            if((l.Email!=Null) &&(trigger.isInsert||(l.Email!=system.trigger.oldmap.get(l.id).Email)))
            {
                if(leadmap.containskey(l.Email))
                {
                    l.Email.adderror(‘+++++++ Duplicasy Occoured FOR Email+++++++’);
                    
                }
                
                else
                {
                    leadmap.put(l.Email,l);
                }
            }
        }
        
        for(lead le:[select Email from lead where Email in:leadmap.keyset()])
        {
            lead newlead = leadmap.get(le.Email);
            newlead.Email.adderror(‘+++++++ Email already exists++++’);
        }

}

Introduction to record ownership, profiles, and sharing

Record owner
The terminology “record owner” is reflected throughout Salesforce and for each and every data record there can be one and only one record owner.
Only users that are active in Salesforce can have records assigned to them.
When a user is marked inactive in Salesforce CRM, they no longer have access to the application. However, any records that these inactive users own remain in the application and continue to show the inactive user as the record owner.
The record owner setting generally determines if access to that record is available to other users within the organization, and is enabled using either profile or sharing settings.
Profiles and sharing
Profiles, sharing, and the optional role hierarchy setting work together and should be considered as a whole when setting up record ownership and data access for users.
An overview of the relationship between users, profiles, and the sharing settings
USER
PROFILE
ROLE SHARING
All users in Salesforce must be assigned a profile. The profile is a control mechanism used to determine which functions the user can perform, which types of data they can access, and which operations they can carry out on that data.

All users are associated with sharing mechanisms in Salesforce which determines the actual records the user can access. Controlling the level of record access can be achieved using options ranging from default sharing, which is set at organizationlevel,
to role hierarchy and beyond using advanced sharing mechanisms. A user does not have to be assigned to a role in Salesforce.

Profiles
Some of the key controls of the profile are to identify the type of license specified for the user, any login hours or IP address restrictions, and control access to objects. If the appropriate object-level permission is not set on the user’s profile then the user
will be unable to access the records of that object type in the application. Profiles never override your organization’s sharing model or role hierarchy. For example, a profile may be set to allow a user access to create, edit, and delete leads.
However, a user with this profile cannot edit or delete other users’ leads if your organization’s lead sharing model is read only.

There are two types of profile in Salesforce—standard and custom—with each standard or custom profile belonging to exactly one user license type.
Standard profiles and custom profiles are similar in nature. The difference being that for standard profiles, the following settings cannot be applied: administrative permissions, general user permissions, and object-level permissions, plus notably the
Password Never Expires setting, which means you are not required to change your password after a certain amount of time (this is a part of the password policies which are described later). Hence, you must create a custom profile, if you want to enable
any of the these features.
There are six standard profile types which are:
• Contract manager
• Marketing user
• System administrator
• Solutions manager
• Standard user
• Read only

Standard profiles have their uses, but it is wise to limit that use
to cloning them to create custom profiles. It is not unknown for
Salesforce to change the settings for standard profiles when a new
release is rolled out which can result in an undesired outcome for
any user assigned with that profile.

Sharing
Sharing settings control the default access for each object across the organization.
Sharing rules per object can grant access beyond the default sharing settings; they cannot restrict access. The default sharing settings are:
• Controlled by Parent
• Private
• Public Read Only
• Public Read/Write
• Public Read/Write/Transfer
• Public Full Access
• Grant Access Using Hierarchies
When the Grant Access Using Hierarchies setting is enabled, the role of the record owner determines visibility throughout the organization. Users in higher roles in the hierarchy will have full access (view/edit/delete) to all records owned by those
lower in the role hierarchy.
If Grant Access Using Hierarchies is not enabled, all roles are treated equally regardless of hierarchy.
Grant Access Using Hierarchies cannot be disabled for standard objects

Roles
Roles is a principal element in sharing rules. Users can be grouped into roles based upon their need for access to data according to how they fit into the role hierarchy. Creating a role for every users’ job title is not required.

Roles are accessed throughout the application and are particularly important for reporting. For instance, if you have two departments “Operations” and “Sales” you can run comparative reports on both roles. Roles generally report to another role and are used to maintain the role hierarchy. It is a one-to-many hierarchical relationship with the hierarchy allowing managers to
see the data of the users that report to them. Users at any given role level are always able to view, edit, and report on all data owned by or shared with users below them in the hierarchy
You can create up to 500 roles for your organization.
Role hierarchies do not need to specifically match your organization chart. Instead, each role in the hierarchy should represent a level of data access required by users.
Permission Sets
Permission Sets allow you to further control access to the system for the users in your organization. They can be considered as a method to fine-tune the permissions for selected individuals and enable access in a similar way to the setting up of profiles.
Permission Sets allow you to grant further access but not to restrict or deny access.
While an individual user can have only one Profile, you can assign multiple permissions and Permission Sets to users. For example, you can create a permission called Convert Leads that provides the facility for converting and Transfer of Leads
and assign it to a user who has a profile which does not provide Lead Conversion.
You can create a permission called Edit Contacts and assign it to a user who has a profile which does not provide Contact editing. You can also group these permissions into a Permission Set to create specific profile-like permissions without
actually having to create or clone complete profiles which are often unnecessary.
You can create up to 1,000 permission sets for your organization.
Permission Sets are an ideal mechanism to apply system access for your users without affecting all other users that have the same profile and without having to create one-off profiles which sometimes leads to increase in the amount of maintenance.