• sam_Admin
  • NEWBIE
  • 313 Points
  • Member since 2010

  • Chatter
    Feed
  • 7
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 78
    Questions
  • 177
    Replies

On a VF page, I have a pageBlockTable.  There are times where there are more than 1000 records in the collection to be rendered.  When this occurs, the Visualforce collection limit of 1000 is hit and the page doesn't load.  I need to figure out a creative solution for getting around this.  In the end...

 

  1. I need all records to render on the page. If I do any pagination, it'll happen client-side after the records are loaded in the HTML.  I know the first responses to this will be about whether I really need to have all those records on the page and how there is doubt about whether I need to, but for the purposes of this forum post, please work with me here.
  2. I want to keep the look and feel of a pageBlockTable if possible.

 

When not using pageBlockTables, I have used a construct similar to the following to get through a collection of more than 1000 items.

 

<apex:repeat value="{!myCollection}" var="item" rows="1000" first="0">
{!item.text}
</apex:repeat>
<apex:repeat value="{!myCollection}" var="item" rows="1000" first="1000">
{!item.text}
</apex:repeat>
<apex:repeat value="{!myCollection}" var="item" rows="1000" first="2000">
{!item.text}
</apex:repeat>

 

pageBlockTable has the rows and first parameters, but if I do that, I'd be getting a new pageBlockTable everytime.

 

The options I can think of are:

 

  • Get a creative solution from the forums to actually utilize the pageBlockTable (purpose of this post)
  • Use apex:dataTable and try to use style classes to mimix the pageBlockTable look and feel. This is a nice possibility I haven't tried yet.
  • Use apex:repeat tags and make up my own HTML styling

 

Any help is appreciated.

 

 

  • September 13, 2010
  • Like
  • 0
I have 2 date time fields, iam trying to calculate the time in days and hours with formula field in 2 decimals, below is the formula i have but right now it only displays in round number, how can i update it so it shows in days and hours

I have 2 date time fields, iam trying to calculate the time in days and hours with formula field in 2 decimals, below is the formula i have but right now it only displays in round number, how can i update it so it shows in days and hours
```
CASE(MOD( DATEVALUE(CreatedDate) - DATE(1985,6,24),7),
0 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),
1 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),
2 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),
3 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),
4 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),
5 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),
6 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),
999)
+
(FLOOR(( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) )/7)*5)
```
We have custom object order managemet which was child object for account (look up field), some of the order management fields gets populated through trigger, but we recently changed the lookup to master detail and receiving error when creating new order file

Trigger updates account info from opp and opp and account info from Quote, so now since we changed it to master details, account is required field and how to modify the trigger so account info gets populated from opp before saving?

/*
######################################################################
Trigger Description: 
           Updates the Opportunity and account information from Quote
######################################################################
*/

trigger UpdateQuoteAccOppty on Order_Management__c (before insert, before update) {
 list<Order_Management__c>olist = new list<Order_Management__c>();
 list<Id>qId= new list<Id>();
 list<Id>oId = new list<id>();
 for(Order_Management__c o : Trigger.New)
  { 
   if(o.Oracle_Quote__c!=null)
    qId.add(o.Oracle_Quote__c);
   if((o.Opportunity__c!=null))
     oId.add(o.Opportunity__c);
  }
if(qId.size()>0){
 system.debug('-----------qId-----------'+qId); 
 list<cafsl__Oracle_Quote__c> bqlist = [Select b.cafsl__Opportunity__c,b.cafsl__Opportunity__r.Amount,b.cafsl__Opportunity__r.CurrencyIsoCode,b.cafsl__Opportunity__r.Owner.Name, b.cafsl__Opportunity__r.CloseDate, b.cafsl__Opportunity__r.AccountId, b.Id From cafsl__Oracle_Quote__c b where b.Id in:qId];
 system.debug('-----------bqlist-----------'+bqlist);
 map<Id,Id>QuoOppMap = new map<Id,Id>();
 map<Id,Id>QuoAccMap = new map<Id,Id>();
 map<Id,Decimal>QuoAmtMap = new map<id,Decimal>();
 map<Id,String>QuoOwnerMap = new map<Id,String>();
 map<Id,String>QuoCURmap = new map<Id,String>();
 map<Id,String>QuoSCmap = new map<Id,String>();
 for(cafsl__Oracle_Quote__c bq: bqlist){
    QuoOppMap.put(bq.id,bq.cafsl__Opportunity__c);
    QuoAccMap.put(bq.id,bq.cafsl__Opportunity__r.AccountId);
    QuoAmtMap.put(bq.id,bq.cafsl__Opportunity__r.Amount);
    QuoOwnerMap.put(bq.id,bq.cafsl__Opportunity__r.Owner.Name);
    QuoCURmap.put(bq.id,bq.cafsl__Opportunity__r.CurrencyIsoCode);
 // QuoSCmap.put(bq.id,bq.cafsl__Opportunity__r.Sales_Channel__c);
 }
 system.debug('-----------QuoOppMap-----------'+QuoOppMap);
 system.debug('-----------QuoAccMap-----------'+QuoAccMap);
 for(Order_Management__c o : Trigger.New){
    if(o.Oracle_Quote__c!=null){
    o.Opportunity__c = QuoOppMap.get(o.Oracle_Quote__c);
    o.Account__c =  QuoAccMap.get(o.Oracle_Quote__c);
    o.Amount__c =  QuoAmtMap.get(o.Oracle_Quote__c);
    o.Opp_Owner__c = QuoOwnerMap.get(o.Oracle_Quote__c);
    o.CurrencyIsoCode = QuoCURmap.get(o.Oracle_Quote__c);
 // o.Sales_Channel__c = QuoSCmap.get(o.Oracle_Quote__c);
   }
 }
}

if(oId.size()>0){
  
  list<Opportunity>opptylist = [Select o.Id,o.Amount,o.CurrencyIsoCode,o.AccountId, o.OwnerId, o.Owner.Name, o.CloseDate From Opportunity o where o.Id in: oId];  
  system.debug('----opptylist--'+opptylist);
  map<Id,Id>OppAccMap = new map<Id,Id>();
  map<Id,Decimal>OppAmtMap = new map<Id,Decimal>();
  map<Id,String>OppOwnerMap = new map<Id,String>();
  map<Id,String>OppCurMap = new map<Id,String>();
  map<Id,String>OppSCMap = new map<Id,String>();
  for(Opportunity o:opptylist){
    OppAccMap.put(o.Id,o.AccountId);
    OppAmtMap.put(o.Id,o.Amount);
    OppOwnerMap.put(o.Id,o.Owner.Name);
    OppCurMap.put(o.Id,o.CurrencyIsoCode);
 // OppSCMap.put(o.Id,o.Sales_Channel__c);
    system.debug('----OppSCMap---'+OppSCMap);
  }
  for(Order_Management__c o : Trigger.New){
     o.Account__c =  OppAccMap.get(o.Opportunity__c);
     o.Amount__c =  OppAmtMap.get(o.Opportunity__c);
     o.Opp_Owner__c = OppOwnerMap.get(o.Opportunity__c);
     o.CurrencyIsoCode = OppCurMap.get(o.Opportunity__c);
  // o.Sales_Channel__c = OppSCMap.get(o.Opportunity__c);

     }
 } 
}
Can someone help with me test class coverage? iam only getting 63%
Trigger:
trigger OppDemoDate on CSActivity__c (before insert, before update) 
{
   Opportunity opt = new  Opportunity();
   
   opt = [select Id,Demo_Date__c from Opportunity where id =:trigger.new[0].OpportunityName__c];
     
    list<CSActivity__c> cslist = [Select c.Start_Date_Time__c, c.OpportunityName__c, c.Id, c.CreatedDate, c.ActivityType__c From CSActivity__c c where c.OpportunityName__c =: opt.id and c.ActivityType__c=:'Demo'  order by c.CreatedDate limit 1];
            
      if(cslist.size()>0)
         {
          if(trigger.new[0].Id == cslist[0].Id){
          opt.Demo_Date__c = trigger.new[0].Start_Date_Time__c;
          update opt;  
          }
         }
         else{
          if(trigger.new[0].ActivityType__c == 'Demo'){
          opt.Demo_Date__c = trigger.new[0].Start_Date_Time__c;
           if(!Test.isRunningTest()){
           update opt;  
          }
          }
        }
 }

Test Class:
@isTest
private class OppDemoDate_test {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test
    
        
      Account acc = new Account(Name = 'test', phone = '1234567890');
      insert acc;
      
      Opportunity opp = new Opportunity(SaleType__c = 'new', Name = 'test', AccountId = acc.Id , 
        Amount = 50, CurrencyIsoCode = 'USD', CloseDate = Date.newInstance(2009,02,01), StageName = 'Closed',
        ForecastCategoryName = 'omitted', Probability_SonoWin__c = '10', Probability_Any_Order__c = '20', SystemType__c = 'Other',
        SystemQty__c = 0, Demo_Date__c = Date.newInstance(2019,02,01) );
      insert opp;
      
      CSActivity__c ccr = new CSActivity__c(Name = 'Test', ActivityType__c = 'Demo', Clinical_Support_Type__c = 'Test', Start_Date_Time__c = Date.newInstance(2009,02,01), Start_Time__c = '0', End_Time__c = '1', Sales_Region__c = 'Test', OpportunityName__c = opp.Id);
      insert ccr;

    }
}
Initially when this was created we only had To, but now our users want to send to more than one contact, i tried to add Cc but it doesn't works, is this possible?

VF: <apex:page standardcontroller="Lead" extensions="DistributorEmailController" showheader="false" lightningstylesheets="true">
    <apex:form >
        <apex:pageBlock title="Please select the Distributor below">
    
            <!--<p>Fill out the fields below to test how you might send an email to a contact.</p>-->
            <br/>    
                <apex:pageMessages />
                <b><apex:outputLabel value="To" for="To"/>:</b><br /> 
                <apex:inputField value="{!leadRecord.Contact__c}" id="To" />
                <br />
                <b><apex:outputLabel value="Cc" for="Cc"/>:</b><br /> 
                <apex:inputField value="{!leadRecord.Contact__c}" id="Cc" />
                <br />                                
                <b><apex:outputLabel value="Subject" for="Subject"/>:</b><br />     
                <apex:outputText value="{!ET.subject}" id="Subject" />
                <br />
                <br />
               <!-- <b><apex:outputLabel value="Body" for="Body"/>:</b><br /> (READ-ONLY: if you want to make changes to content, please update Email template and try again.)-->
                <apex:inputTextArea value="{!htmlBody}" id="Body"  rows="30" cols="80" richText="true" disabled="true" /> 
                <br /><br /><br />
                <apex:commandButton value="Send Email" action="{!send}" />
                <apex:commandButton value="Cancel & Return" action="{!Cancel}" /> 
        </apex:pageBlock>     
    </apex:form>
</apex:page>

Apex Class: /*Controller to send This lead to any selected Contact */

public class DistributorEmailController {
    public Lead leadRecord {get;set;}   
    public String TemplateID {get;set;}
    public String subject { get; set; }
    public String body { get; set; }
    public String htmlBody { get; set; }          
    public EmailTemplate  ET{ get; set; }
    public DistributorEmailController(ApexPages.StandardController controller) {
        String lid = '';
        TemplateID = ''; 
        htmlBody ='';
        if(ApexPages.currentPage().getParameters().get('id') != null )
            lid = ApexPages.currentPage().getParameters().get('id');
         system.debug('lidid ' + lid );    
            
        try{             
            leadRecord = [select Status,ID,Contact__c,Name,Company,NumberOfEmployees,Street,City,State,PostalCode,Country,Website,Salutation,FirstName,
                         LastName,Title,Department__c,Email,Phone,MobilePhone,Fax,Product__c,Industry,Specialty__c,Rating,BuyingTimeframe__c,LeadSource,WebFormDetail__c,
                         Description,Marketing_Comments__c from Lead where id = : lid];
            //Change the Template name below.
            ET = [Select ID,HTMLValue,Subject from EmailTemplate  where   name = 'Distributor Lead Email' ];            
            if (ET != null){
                TemplateID  = ET.id;        
                htmlBody  = ET.HTMLValue ;
                Subject = ET.Subject;
                ReplaceTags();   
            }
        }
        catch(Exception e){
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.Error,e.getMessage()));
        }
    }                  
    
    public void ReplaceTags(){
        
        if(htmlBody.indexOf('{!Lead.Id}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Id}',nullToString(leadRecord.Id));
                
        if(htmlBody.indexOf('{!Lead.Name}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Name}',nullToString(leadRecord.Name));
                    
        if(htmlBody.indexOf('{!Lead.Company}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Company}',nullToString(leadRecord.Company));
        
        if(htmlBody.indexOf('{!Lead.NumberOfEmployees}') >-1)
            htmlBody = htmlBody.replace('{!Lead.NumberOfEmployees}',nullToString(String.valueOf(leadRecord.NumberOfEmployees)));
            
        if(htmlBody.indexOf('{!Lead.Address}') >-1){
            String Address = '' ;
            Address =  Address  + nullToString(String.valueOf(leadRecord.Street));
            Address =  Address  + ' ' + nullToString(leadRecord.City);
            Address =  Address  + ','+ nullToString(leadRecord.State);
            Address =  Address  + ' ' + nullToString(leadRecord.PostalCode);
            Address =  Address  + ' ' + nullToString(leadRecord.Country);
            htmlBody = htmlBody.replace('{!Lead.Address}',Address);
            
        }
        if(htmlBody.indexOf('{!Lead.Street}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Street}',nullToString(String.valueOf(leadRecord.Street)));
            
        if(htmlBody.indexOf('{!Lead.City}') >-1)
            htmlBody = htmlBody.replace('{!Lead.City}',nullToString(leadRecord.City));
        
        if(htmlBody.indexOf('{!Lead.State}') >-1)
            htmlBody = htmlBody.replace('{!Lead.State}',nullToString(leadRecord.State));
            
        if(htmlBody.indexOf('{!Lead.PostalCode}') >-1)
           htmlBody = htmlBody.replace('{!Lead.PostalCode}',nullToString(leadRecord.PostalCode));
           
        if(htmlBody.indexOf('{!Lead.Country}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Country}',nullToString(leadRecord.Country));
            
        if(htmlBody.indexOf('{!Lead.Website}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Website}',nullToString(leadRecord.Website));
            
        if(htmlBody.indexOf('{!Lead.Salutation} ') >-1)
            htmlBody = htmlBody.replace('{!Lead.Salutation} ',nullToString(leadRecord.Salutation) );
            
        if(htmlBody.indexOf('{!Lead.FirstName} ') >-1)
            htmlBody = htmlBody.replace('{!Lead.FirstName} ',nullToString(leadRecord.FirstName) );
            
        if(htmlBody.indexOf('{!Lead.LastName}') >-1)
            htmlBody = htmlBody.replace('{!Lead.LastName}',nullToString(leadRecord.LastName));
            
        if(htmlBody.indexOf('{!Lead.Title}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Title}',nullToString(leadRecord.Title));
            
        if(htmlBody.indexOf('{!Lead.Department__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Department__c}',nullToString(leadRecord.Department__c));
        
        if(htmlBody.indexOf('{!Lead.Email}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Email}',nullToString(leadRecord.Email));
            
        if(htmlBody.indexOf('{!Lead.Phone}') >-1)
           htmlBody = htmlBody.replace('{!Lead.Phone}',nullToString(leadRecord.Phone));
           
        if(htmlBody.indexOf('{!Lead.MobilePhone}') >-1)
            htmlBody = htmlBody.replace('{!Lead.MobilePhone}',nullToString(leadRecord.MobilePhone));
            
        if(htmlBody.indexOf('{!Lead.Fax}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Fax}',nullToString(leadRecord.Fax));
            
        if(htmlBody.indexOf('{!Lead.Product__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Product__c}',nullToString(leadRecord.Product__c));
            
        if(htmlBody.indexOf('{!Lead.Industry}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Industry}',nullToString(leadRecord.Industry));
            
        if(htmlBody.indexOf('{!Lead.Specialty__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Specialty__c}',nullToString(leadRecord.Specialty__c));
            
        if(htmlBody.indexOf('{!Lead.Rating}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Rating}',nullToString(leadRecord.Rating));
            
        if(htmlBody.indexOf('{!Lead.BuyingTimeframe__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.BuyingTimeframe__c}',nullToString(leadRecord.BuyingTimeframe__c));
            
        if(htmlBody.indexOf('{!Lead.LeadSource}') >-1)
            htmlBody = htmlBody.replace('{!Lead.LeadSource}',nullToString(leadRecord.LeadSource));
            
        if(htmlBody.indexOf('{!Lead.WebFormDetail__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.WebFormDetail__c}',nullToString(leadRecord.WebFormDetail__c));
            
        if(htmlBody.indexOf('{!Lead.Description}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Description}',nullToString(leadRecord.Description));
            
        if(htmlBody.indexOf('{!Lead.Marketing_Comments__c}') >-1)
            htmlBody = htmlBody.replace('{!Lead.Marketing_Comments__c}',nullToString(leadRecord.Marketing_Comments__c));
                    
    }
    public PageReference send() {
     List<Messaging.SingleEmailMessage> email = new List<Messaging.SingleEmailMessage>();
     
        if(leadRecord.Contact__c == null){
             ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Please select contact and Try again.'));
             return null;   
        }
     
        if (TemplateID != null){
            // Query Contact Email ID
             try{
                Contact c =  [Select Id,Email,Name from Contact where ID =: leadRecord.Contact__c]; 
                if (c.Email != null && c.Email != ''){ 
                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                        
                      if(htmlBody.indexOf('{!Contact.Name}') >-1)
                          htmlBody = htmlBody.replace('{!Contact.Name}',nullToString(c.name));
                        String[] toAddresses = new String[] {c.email};
                        String[] ccAddresses = new String[] {c.email};
                        mail.setTargetObjectId(c.id);
                        mail.setSubject(Subject);
                        mail.setToAddresses(toAddresses);
                        mail.setCcAddresses(ccAddresses);
                        mail.setHtmlBody(HtmlBody); 
                        mail.setsaveAsActivity(true);
                        mail.setTreatTargetObjectAsRecipient(false); 
                        mail.setTargetObjectId(LeadRecord.Id);                                     
                    email.add(mail);
                    Messaging.sendEmail(email);                      
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Email sent successfully!'));
                    
                    leadRecord.Status = 'Dealer (ISR Only)';
                    update leadRecord;
                }
                else{
                    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Selected Contact has no Valid Email Address, kindly update the contact and Try again.'));
                    return null;   
                }
             }catch(Exception e){}
        }
                
        return new PageReference('/' + leadRecord.id);  
    }
    public String nullToString(String s){
        if (s== null)
            return '';
        else 
            return s;           
    }
    public PageReference cancel(){
        return new PageReference('/' + leadRecord.id);  
    }
}
Issue: Below trigger forwards opp if opp name contains "TrailHead", our users are entering "Trailhead" and opp is not forwarding, it's getting forwarded if i use "TrailHead", i have used contains so why is my trigger using case sensitive?

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isafter  && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a
        //criteria to ensure only the appropriate connection record is returned.
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName
             From PartnerNetworkConnection
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Name.contains('TrailHead')){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID, Name, Account.Id From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                    LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                          //ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }
            
            //Insert record connections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }
    }
}
Description: When the Primary campaign field from the Opp is Null then that field is updated by the most recent campaign from the primary contact role

Apex class: 

    global class UpdPrimaryCampaignOnOpty implements Database.Batchable<sObject>,Schedulable{
    
        global String Query;
        global UpdPrimaryCampaignOnOpty(){ 
            query = 'Select Id, contactId, opportunityId,isPrimary from OpportunityContactRole where (createddate = today or lastmodifieddate = today) and  opportunity.CampaignId = null';
        }
        
        global void execute(SchedulableContext SC){
            UpdPrimaryCampaignOnOpty upc =  new UpdPrimaryCampaignOnOpty();
            ID batchprocessid = Database.executeBatch(upc);
        }
        
         global DataBase.QueryLocator start(Database.BatchableContext BC){ 
            return Database.getQueryLocator(query);
        }
        global void execute(Database.BatchableContext BC, List<sObject> scope){
            System.debug('scope size = '+scope.size());
            set<Id> conIds = new Set<Id>();
            Set<Id> optyIds = new Set<Id>();
            Map<Id,Id> optyConMap = new Map<Id,Id>();
            for(sObject s : scope){
                OpportunityContactRole ocr = (OpportunityContactRole)s;
                if(ocr.isPrimary){
                    conIds.add(ocr.contactId);
                    optyIds.add(ocr.opportunityId);
                    optyConMap.put(ocr.OpportunityId, ocr.ContactId);
                }
            }
            System.debug('conIds size = '+conIds.size());
            System.debug('optyIds size = '+optyIds.size());
            System.debug('optyConMap size = '+optyConMap.size());
            
            List<CampaignMember> cmList = [Select id, CampaignId, ContactId, Campaign.createddate from CampaignMember where ContactId IN :conIds];
            System.debug('cmList size = '+cmList.size());
            Map<Id,CampaignMember> contactCampaignMap = new Map<Id,CampaignMember>();
            for(CampaignMember cm : cmList){
                
                if(contactCampaignMap.containsKey(cm.contactId) && cm.Campaign.createddate > contactCampaignMap.get(cm.contactId).Campaign.CreatedDate ){
                    contactCampaignMap.put(cm.contactId, cm);
                }
                else{
                    contactCampaignMap.put(cm.contactId, cm);
                }           
            }
            
            List<Opportunity> optyList = [Select Id, CampaignId from Opportunity where Id IN :optyIds];
            
            for(Opportunity opty : optyList){
                if(optyConMap.containsKey(opty.id) && contactCampaignMap.containsKey(optyConMap.get(opty.Id))){
                    opty.CampaignId = contactCampaignMap.get(optyConMap.get(opty.Id)).CampaignId;
                }        
            }
            
            update optyList;
            
        }
        
        global void finish(Database.BatchableContext BC){
           
       }
            
    }
We have "Location" field on Opportunity with picklist values and we have "Opp_Location__c" field on the account, this trigger displays the values of "Location" field into "Opp_Location__c" field, how to modify the trigger so i can map the same values and not display it more than once? for ex i have picklist value "Hospital" and if the account has 10 opps with same hospital location then i want to display it only one time 


trigger RollupLocation on Opportunity (after insert, after update) { 
  Map<ID, Account > parentOpps = new Map<ID, Account>(); 
  Set<Id> listIds = new Set<Id>();

  for (Opportunity childObj : Trigger.new) {
    listIds.add(childObj.AccountId);
  }

  parentOpps = new Map<Id, Account>([SELECT id, Opp_Location__c ,
                                        (SELECT ID, Location_Type__c  FROM Opportunities) 
                                    FROM Account WHERE ID IN :listIds]);

  List<Account> lstAccount = new List<Account>();

  for(Account acct:parentOpps.values())
  {  
      List<String> strType = new List<String>();
      for(Opportunity opty:acct.Opportunities)
      {
          strType.add(opty.Location_Type__c);
      }
      acct.Opp_Location__c = String.join(strType,',');

  }

  update parentOpps.values();
}
I have the below triggers and test class for them, Trigger-1 has 85% coverage and Trigger-2 has 66%, can anyone please help me in improving code coverage? Highlighted lines in bold which are not covering 

Trigger-1:   

    trigger AccountName_Opp on Opportunity (before insert, before update ){
    
        Map<String, Opportunity> OppMap = new Map<String, Opportunity>();
    
        for(Opportunity opp:Trigger.new)
        {
            OppMap.put(opp.Account_Name__c, opp);
    
        }
    
        List<Account> accLst = [SELECT ID, Name FROM Account where Name in :OppMap.keySet()];
    
        for(Account acct : accLst){
            OppMap.get(acct.Name).AccountId = acct.ID;
        }
    }

Trigger-2: 

    trigger AccountName_Contact on Contact (before insert, before update ){
    
        Set<String> conaccounts = new Set<String>();
    
        for(Contact con:Trigger.new)
        {
            conaccounts.add(con.Account_Name__c);
        }
    
        List<Account> accLst = [SELECT ID, Name FROM Account where Name in :conaccounts];
        System.debug(accLst);
        for(Account acct : accLst){
            for(Contact co : Trigger.new){
                if(co.Account_Name__c == acct.Name)
                    co.accountid = acct.id;

            }        
        }
    
    }

Testclass:
 

    @istest
    public class FFCNAccountName
    {
      static testmethod void myTest()
      {
        Map<String, Opportunity> OppMap = new Map<String, Opportunity>();
        
        Account acc = new Account(Name = 'test', phone = '1234567890');
        insert acc;
        
        Opportunity opp = new Opportunity(SaleType__c = 'new', Name = 'test', AccountId = acc.Id, Amount = 50, CurrencyIsoCode = 'USD');
        insert opp;
        
        Contact con = new Contact( LastName = 'Test2', Email = 'test.user@gmail.com', AccountId = acc.Id );
        insert con;
      }
    }
Can anyone help me with test class for below trigger?

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isafter  && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a
        //criteria to ensure only the appropriate connection record is returned.
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName
             From PartnerNetworkConnection
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Name.contains('US')|| oppRecord.Name.contains('VSI')){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID, Name, Account.Id From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                     LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                         // ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }//for
            
            //Insert record connections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }//if
    }
}
I got this error when i edit the record, how to fix it? Apex trigger AutoforwardOpp caused an unexpected exception, contact your administrator: AutoforwardOpp: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Contact.AccountId: Trigger.AutoforwardOpp: line 91, column 1

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a 
        //criteria to ensure only the appropriate connection record is returned. 
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName 
             From PartnerNetworkConnection 
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Department__c == 'US'){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID,Name From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                    LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                            ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }//for
            
            //Insert record conneections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }//if
    }
}
Right now I am using the below trigger to forward an Opportunity via Salesforce2Salesforce. Is it possible to transfer related contacts along with account?
Trigger Description: Whenever Department is set to "US" then the Opp automatically gets forwarded to Connection


Trigger AutoforwardOpp on Opportunity(after insert, before update)
{
    String UserName = UserInfo.getName();
    String orgName = UserInfo.getOrganizationName();
    List<PartnerNetworkConnection> connectionList = new List<PartnerNetworkConnection>();
    List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>
    ([select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted']);
    List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();

    for(Integer i =0; i< Trigger.size; i++)
    {
        Opportunity opp = Trigger.new[i];
        String oId = opp.Id;
        String accId = opp.AccountId;
        for(PartnerNetworkConnection network : connMap)
        {

            String cid = network.Id;
            String status = network.ConnectionStatus;
            String connName = network.ConnectionName;

            if(opp.Department__c == 'US')
            {
                PartnerNetworkRecordConnection newAccRecord = new PartnerNetworkRecordConnection();
                newAccRecord.ConnectionId = cid;
                newAccRecord.LocalRecordId = accId;
                newAccRecord.SendClosedTasks = true;
                newAccRecord.SendOpenTasks = true;
                newAccRecord.SendEmails = true;
                System.debug('Inserting New Record'+newAccrecord);
                insert newAccrecord;

                PartnerNetworkRecordConnection newOpprecord = new PartnerNetworkRecordConnection();
                newOpprecord.ConnectionId = cid;
                newOpprecord.LocalRecordId = oId;
                newOpprecord.SendClosedTasks = true;
                newOpprecord.SendOpenTasks = true;
                newOpprecord.SendEmails = true;
                System.debug('Inserting New Record'+newOpprecord);
                insert newOpprecord;
            }
        }
    }
}
Is there anyway to restrict assigning same contact with different roles on opportunity?
Ex: I have "Test opportunity" and under contact roles i have contact "Joseph" that's been assigned twice as primary with different roles. I just want to know if there is any possibility to restrict assigning same contact again if it already exists under contact role
We have a VF custom button on lead record that sends email to a selected contact but when the email is sent it doesn't shows up on lead activity history, is there any way to track the emails being sent through this button?


Apex class:

    /*Controller to send This lead to any selected Contact */
    
    public class EmailController {
        public Lead leadRecord {get;set;}   
        public String TemplateID {get;set;}
        public String subject { get; set; }
        public String body { get; set; }
        public String htmlBody { get; set; }          
        public EmailTemplate  ET{ get; set; }
        public EmailController(ApexPages.StandardController controller) {
            String lid = '';
            TemplateID = ''; 
            htmlBody ='';
            if(ApexPages.currentPage().getParameters().get('id') != null )
                lid = ApexPages.currentPage().getParameters().get('id');
             system.debug('lidid ' + lid );    
    
            try{             
                leadRecord = [select Status,ID,Contact__c,Name,Company,NumberOfEmployees,Street,City,State,PostalCode,Country,Website,Salutation,FirstName,
                             LastName,Title,Department__c,Email,Phone,MobilePhone,Fax,Product__c,Industry,Specialty__c,Rating,BuyingTimeframe__c,LeadSource,WebFormDetail__c,
                             Description,Marketing_Comments__c from Lead where id = : lid];
                //Change the Template name below.
                ET = [Select ID,HTMLValue,Subject from EmailTemplate  where   name = 'Lead Email' ];            
                if (ET != null){
                    TemplateID  = ET.id;        
                    htmlBody  = ET.HTMLValue ;
                    Subject = ET.Subject;
                    ReplaceTags();   
                }
            }
            catch(Exception e){
                ApexPages.addMessage(new ApexPages.message(ApexPages.severity.Error,e.getMessage()));
            }
        }                  
    
        public void ReplaceTags(){
    
            if(htmlBody.indexOf('{!Lead.Id}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Id}',nullToString(leadRecord.Id));
    
            if(htmlBody.indexOf('{!Lead.Name}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Name}',nullToString(leadRecord.Name));
    
            if(htmlBody.indexOf('{!Lead.Company}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Company}',nullToString(leadRecord.Company));
    
            if(htmlBody.indexOf('{!Lead.NumberOfEmployees}') >-1)
                htmlBody = htmlBody.replace('{!Lead.NumberOfEmployees}',nullToString(String.valueOf(leadRecord.NumberOfEmployees)));
    
            if(htmlBody.indexOf('{!Lead.Address}') >-1){
                String Address = '' ;
                Address =  Address  + nullToString(String.valueOf(leadRecord.Street));
                Address =  Address  + ' ' + nullToString(leadRecord.City);
                Address =  Address  + ','+ nullToString(leadRecord.State);
                Address =  Address  + ' ' + nullToString(leadRecord.PostalCode);
                Address =  Address  + ' ' + nullToString(leadRecord.Country);
                htmlBody = htmlBody.replace('{!Lead.Address}',Address);
    
            }
            if(htmlBody.indexOf('{!Lead.Street}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Street}',nullToString(String.valueOf(leadRecord.Street)));
    
            if(htmlBody.indexOf('{!Lead.City}') >-1)
                htmlBody = htmlBody.replace('{!Lead.City}',nullToString(leadRecord.City));
    
            if(htmlBody.indexOf('{!Lead.State}') >-1)
                htmlBody = htmlBody.replace('{!Lead.State}',nullToString(leadRecord.State));
    
            if(htmlBody.indexOf('{!Lead.PostalCode}') >-1)
               htmlBody = htmlBody.replace('{!Lead.PostalCode}',nullToString(leadRecord.PostalCode));
    
            if(htmlBody.indexOf('{!Lead.Country}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Country}',nullToString(leadRecord.Country));
    
           
            if(htmlBody.indexOf('{!Lead.FirstName} ') >-1)
                htmlBody = htmlBody.replace('{!Lead.FirstName} ',nullToString(leadRecord.FirstName) );
    
            if(htmlBody.indexOf('{!Lead.LastName}') >-1)
                htmlBody = htmlBody.replace('{!Lead.LastName}',nullToString(leadRecord.LastName));
    
            if(htmlBody.indexOf('{!Lead.Title}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Title}',nullToString(leadRecord.Title));
                  
    
        }
        public PageReference send() {
         List<Messaging.SingleEmailMessage> email = new List<Messaging.SingleEmailMessage>();
    
            if(leadRecord.Contact__c == null){
                 ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Please select contact and Try again.'));
                 return null;   
            }
    
            if (TemplateID != null){
                // Query Contact Email ID
                 try{
                    Contact c =  [Select Id,Email,Name from Contact where ID =: leadRecord.Contact__c]; 
                    if (c.Email != null && c.Email != ''){ 
                        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    
                            if(htmlBody.indexOf('{!Contact.Name}') >-1)
                                htmlBody = htmlBody.replace('{!Contact.Name}',nullToString(c.name));
    
                            mail.setTargetObjectId(c.id);
                            mail.setSubject(Subject);
                            mail.setHtmlBody(HtmlBody);
                            mail.setsaveAsActivity(true);                     
                        email.add(mail);
                        Messaging.sendEmail(email);
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Email sent successfully!'));
    
                        leadRecord.Status = 'Tracking';
                        update leadRecord;
                    }
                    else{
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Selected Contact has no Valid Email Address, kindly update the contact and Try again.'));
                        return null;   
                    }
                 }catch(Exception e){}
            }
    
            return new PageReference('/' + leadRecord.id);  
        }
        public String nullToString(String s){
            if (s== null)
                return '';
            else 
                return s;           
        }
        public PageReference cancel(){
            return new PageReference('/' + leadRecord.id);  
        }
    } 

VF Page: <apex:page standardcontroller="Lead" extensions="EmailController" showheader="false">
    <apex:form >
        <apex:pageBlock title="Please select the Contact below">
    
            <br/>    
                <apex:pageMessages />
                <b><apex:outputLabel value="To" for="To"/>:</b><br /> 
                <apex:inputField value="{!leadRecord.Contact__c}" id="To" />
                <br />
                <br />                                
                <b><apex:outputLabel value="Subject" for="Subject"/>:</b><br />     
                <apex:outputText value="{!ET.subject}" id="Subject" />
                <br />
                <br />               
                <apex:inputTextArea value="{!htmlBody}" id="Body"  rows="30" cols="80" richText="true" disabled="true" /> 
                <br /><br /><br />
                <apex:commandButton value="Send Email" action="{!send}" />
                <apex:commandButton value="Cancel & Return" action="{!Cancel}" /> 
        </apex:pageBlock>     
    </apex:form>
</apex:page>
I have a custom button on lead detail page, so we send lead details through this button to a contact, how do i track the email in activity history on lead record? here is my class

    /*Controller to send This lead to any selected Contact */
    
    public class EmailController {
        public Lead leadRecord {get;set;}   
        public String TemplateID {get;set;}
        public String subject { get; set; }
        public String body { get; set; }
        public String htmlBody { get; set; }          
        public EmailTemplate  ET{ get; set; }
        public EmailController(ApexPages.StandardController controller) {
            String lid = '';
            TemplateID = ''; 
            htmlBody ='';
            if(ApexPages.currentPage().getParameters().get('id') != null )
                lid = ApexPages.currentPage().getParameters().get('id');
             system.debug('lidid ' + lid );    
                
            try{             
                leadRecord = [select Status,ID,Contact__c,Name,Company,NumberOfEmployees,Street,City,State,PostalCode,Country,Website,Salutation,FirstName,
                             LastName,Title,Department__c,Email,Phone,MobilePhone,Fax,Product__c,Industry,Specialty__c,Rating,BuyingTimeframe__c,LeadSource,WebFormDetail__c,
                             Description,Marketing_Comments__c from Lead where id = : lid];
                //Change the Template name below.
                ET = [Select ID,HTMLValue,Subject from EmailTemplate  where   name = 'Lead Email' ];            
                if (ET != null){
                    TemplateID  = ET.id;        
                    htmlBody  = ET.HTMLValue ;
                    Subject = ET.Subject;
                    ReplaceTags();   
                }
            }
            catch(Exception e){
                ApexPages.addMessage(new ApexPages.message(ApexPages.severity.Error,e.getMessage()));
            }
        }                  
        
        public void ReplaceTags(){
            
            if(htmlBody.indexOf('{!Lead.Id}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Id}',nullToString(leadRecord.Id));
                    
            if(htmlBody.indexOf('{!Lead.Name}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Name}',nullToString(leadRecord.Name));
                        
            if(htmlBody.indexOf('{!Lead.Company}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Company}',nullToString(leadRecord.Company));
            
            if(htmlBody.indexOf('{!Lead.NumberOfEmployees}') >-1)
                htmlBody = htmlBody.replace('{!Lead.NumberOfEmployees}',nullToString(String.valueOf(leadRecord.NumberOfEmployees)));
                
            if(htmlBody.indexOf('{!Lead.Address}') >-1){
                String Address = '' ;
                Address =  Address  + nullToString(String.valueOf(leadRecord.Street));
                Address =  Address  + ' ' + nullToString(leadRecord.City);
                Address =  Address  + ','+ nullToString(leadRecord.State);
                Address =  Address  + ' ' + nullToString(leadRecord.PostalCode);
                Address =  Address  + ' ' + nullToString(leadRecord.Country);
                htmlBody = htmlBody.replace('{!Lead.Address}',Address);
                
            }
            if(htmlBody.indexOf('{!Lead.Street}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Street}',nullToString(String.valueOf(leadRecord.Street)));
                
            if(htmlBody.indexOf('{!Lead.City}') >-1)
                htmlBody = htmlBody.replace('{!Lead.City}',nullToString(leadRecord.City));
            
            if(htmlBody.indexOf('{!Lead.State}') >-1)
                htmlBody = htmlBody.replace('{!Lead.State}',nullToString(leadRecord.State));
                
            if(htmlBody.indexOf('{!Lead.PostalCode}') >-1)
               htmlBody = htmlBody.replace('{!Lead.PostalCode}',nullToString(leadRecord.PostalCode));
               
            if(htmlBody.indexOf('{!Lead.Country}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Country}',nullToString(leadRecord.Country));
                
            if(htmlBody.indexOf('{!Lead.Website}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Website}',nullToString(leadRecord.Website));
                
            if(htmlBody.indexOf('{!Lead.Salutation} ') >-1)
                htmlBody = htmlBody.replace('{!Lead.Salutation} ',nullToString(leadRecord.Salutation) );
                
            if(htmlBody.indexOf('{!Lead.FirstName} ') >-1)
                htmlBody = htmlBody.replace('{!Lead.FirstName} ',nullToString(leadRecord.FirstName) );
                
            if(htmlBody.indexOf('{!Lead.LastName}') >-1)
                htmlBody = htmlBody.replace('{!Lead.LastName}',nullToString(leadRecord.LastName));
                
            if(htmlBody.indexOf('{!Lead.Title}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Title}',nullToString(leadRecord.Title));
                
            if(htmlBody.indexOf('{!Lead.Department__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Department__c}',nullToString(leadRecord.Department__c));
            
            if(htmlBody.indexOf('{!Lead.Email}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Email}',nullToString(leadRecord.Email));
                
            if(htmlBody.indexOf('{!Lead.Phone}') >-1)
               htmlBody = htmlBody.replace('{!Lead.Phone}',nullToString(leadRecord.Phone));
               
            if(htmlBody.indexOf('{!Lead.MobilePhone}') >-1)
                htmlBody = htmlBody.replace('{!Lead.MobilePhone}',nullToString(leadRecord.MobilePhone));
                
            if(htmlBody.indexOf('{!Lead.Fax}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Fax}',nullToString(leadRecord.Fax));
                
            if(htmlBody.indexOf('{!Lead.Product__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Product__c}',nullToString(leadRecord.Product__c));
                
            if(htmlBody.indexOf('{!Lead.Industry}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Industry}',nullToString(leadRecord.Industry));
                
            if(htmlBody.indexOf('{!Lead.Specialty__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Specialty__c}',nullToString(leadRecord.Specialty__c));
                
            if(htmlBody.indexOf('{!Lead.Rating}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Rating}',nullToString(leadRecord.Rating));
                
            if(htmlBody.indexOf('{!Lead.BuyingTimeframe__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.BuyingTimeframe__c}',nullToString(leadRecord.BuyingTimeframe__c));
                
            if(htmlBody.indexOf('{!Lead.LeadSource}') >-1)
                htmlBody = htmlBody.replace('{!Lead.LeadSource}',nullToString(leadRecord.LeadSource));
                
            if(htmlBody.indexOf('{!Lead.WebFormDetail__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.WebFormDetail__c}',nullToString(leadRecord.WebFormDetail__c));
                
            if(htmlBody.indexOf('{!Lead.Description}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Description}',nullToString(leadRecord.Description));
                
            if(htmlBody.indexOf('{!Lead.Marketing_Comments__c}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Marketing_Comments__c}',nullToString(leadRecord.Marketing_Comments__c));
                        
        }
        public PageReference send() {
         List<Messaging.SingleEmailMessage> email = new List<Messaging.SingleEmailMessage>();
         
            if(leadRecord.Contact__c == null){
                 ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Please select contact and Try again.'));
                 return null;   
            }
         
            if (TemplateID != null){
                // Query Contact Email ID
                 try{
                    Contact c =  [Select Id,Email,Name from Contact where ID =: leadRecord.Contact__c]; 
                    if (c.Email != null && c.Email != ''){ 
                        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                            
                            if(htmlBody.indexOf('{!Contact.Name}') >-1)
                                htmlBody = htmlBody.replace('{!Contact.Name}',nullToString(c.name));
                            
                            mail.setTargetObjectId(c.id);
                            mail.setSubject(Subject);
                            mail.setHtmlBody(HtmlBody);
                         // mail.setWhatId('{lead.id}');                     
                        email.add(mail);
                        Messaging.sendEmail(email);
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Email sent successfully!'));
                        
                        leadRecord.Status = 'Tracking';
                        update leadRecord;
                    }
                    else{
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Selected Contact has no Valid Email Address, kindly update the contact and Try again.'));
                        return null;   
                    }
                 }catch(Exception e){}
            }
                    
            return new PageReference('/' + leadRecord.id);  
        }
        public String nullToString(String s){
            if (s== null)
                return '';
            else 
                return s;           
        }
        public PageReference cancel(){
            return new PageReference('/' + leadRecord.id);  
        }
    }
I want to update the email optout field from converted contact to the existing contacts. For ex lets say i have 3 contacts with same email address(email@gmail.com) and emailoptout not checked and iam converting new lead with emailoptout box checked and has same email(email@gmail.com), i want my trigger to update the email optout box to true on these 3 existing contacts. 

trigger updateLeadOnEmailOptOut on Lead (after update) {
    List<Lead> duplicateLeads = new List<Lead>();
    Map<String, Lead> leadEmailMap = new Map<String, Lead>();
    Map<Id, Lead> leadIdMap = new Map<Id, Lead>();
    Map<Id, Contact> contacts = new Map<Id, Contact>();

    for (Integer i = 0; i < Trigger.new.size(); i++) {
        if (Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail) {
            leadEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
            leadIdMap.put(Trigger.old[i].id, Trigger.new[i]);        
        }
    }    

    If (leadIdMap.size()>0) {


        for (Lead dupLead : [SELECT Id, Name, Email, HasOptedOutOfEmail
                             FROM Lead
                             WHERE Email IN : leadEmailMap.KeySet()
                             AND Id NOT IN : leadIdMap.KeySet()
                             AND IsConverted = FALSE]) {
                                 Lead lead = leadEmailMap.get(dupLead.Email);
                                 If (dupLead.HasOptedOutOfEmail <> lead.HasOptedOutOfEmail) { 
                                     dupLead.HasOptedOutOfEmail = lead.HasOptedOutOfEmail;   
                                     duplicateLeads.add(dupLead);
                                 }
                             }    

        If (duplicateLeads.size()>0) update duplicateLeads;
    }
    for(Lead record: Trigger.new) {
        if(record.ConvertedContactId != null) {
            contacts.put(record.ConvertedContactId, new Contact(Id=record.ConvertedContactId, HasOptedOutOfEmail=record.HasOptedOutOfEmail));
        }
    }
    update contacts.values(); 
}
What am I doing wrong? If the date is less than today then it has to be red if it is greater than today then it should be green

<apex:column >
              <apex:facet name="header">Expires</apex:facet>
             <apex:outputText style="font-weight: bold;color:{!if(ib.verboseWarrantyExpirationDate < {!today()}, 'red', if(ib.verboseWarrantyExpirationDate > {!today()},'green'))};" value="{!ib.verboseWarrantyExpirationDate}"/>
</apex:column>
 
I want to create visualforce template to approve/reject record when a record is submitted for approval. Approval manager travels and he wants an external link to approve rather than going into salesforce so i created text template and used {!ApprovalRequest.External_URL} but this merge field doesn't works and confirmed that it's salesforce bug so is it possible to create an visualforce template with comments box and approve/reject button?
I created Java script button but iam receving this error "A problem with the OnClick JavaScript for this button or link was encountered:
missing ; before statement". Here is my code

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}

var Status = '{!ELA__c.Status__c}';

if(Status == "Active") {window.location = "/a02/e?retURL={!ELA__c.Id}&RecordType=01240000000M83B&00N40000002Hvox="ELA"&00N40000003BOiQ={!ELA__c.Name}&00N40000002HvWZ="IRB""}
else if(Status == "Inactive"){window.location = "/a02/e?retURL={!ELA__c.Id}&RecordType=01240000000M83B&00N40000002Hvox="BLA"&00N40000003BOiQ={!ELA__c.Name}&00N40000002HvWZ="CRB""}
 
Hi,
   I tried creating this button but iam getting this error "A problem with the OnClick JavaScript for this button or link was encountered:invalid regular expression flag e". What iam doing wrong?

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}

var Status = '{!ELA__c.Status__c}';

if(Status == "Active")
{window.location = /a02/e?
retURL=%2F{!ELA__c.Id}
&RecordType=01240000000M83B
&00N40000002Hvox="ELA"
&00N40000003BOiQ={!ELA__c.Name}
&00N40000002HvWZ="IRB"
}
else if(Status = "Inactive")
{window.location = /a02/e?
retURL=%2F{!ELA__c.Id}
&RecordType=01240000000M83B
&00N40000002Hvox="BLA"
&00N40000003BOiQ={!ELA__c.Name}
&00N40000002HvWZ="CRB"
}
I have 2 custom objects, object1(Parent) and object2(Child), i want a clone button on object1 so everytime i clone then it needs to carry over records from object2. I created this button but it doesn't carry over the related records, i know i haven't added any logic to carry the records yet but if anyone can help me here i would really appreciate it

https://na2.salesforce.com/{!object1__c.Id}/e?clone=1&retURL=%{!object1.Id}
Can anyone help me with test class for below trigger?

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isafter  && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a
        //criteria to ensure only the appropriate connection record is returned.
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName
             From PartnerNetworkConnection
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Name.contains('US')|| oppRecord.Name.contains('VSI')){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID, Name, Account.Id From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                     LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                         // ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }//for
            
            //Insert record connections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }//if
    }
}
I have 2 date time fields, iam trying to calculate the time in days and hours with formula field in 2 decimals, below is the formula i have but right now it only displays in round number, how can i update it so it shows in days and hours

I have 2 date time fields, iam trying to calculate the time in days and hours with formula field in 2 decimals, below is the formula i have but right now it only displays in round number, how can i update it so it shows in days and hours
```
CASE(MOD( DATEVALUE(CreatedDate) - DATE(1985,6,24),7),
0 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),
1 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),
2 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),
3 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),
4 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),
5 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),
6 , CASE( MOD( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),
999)
+
(FLOOR(( DATEVALUE(Time_to_completed__c) - DATEVALUE(CreatedDate) )/7)*5)
```
Description: When the Primary campaign field from the Opp is Null then that field is updated by the most recent campaign from the primary contact role

Apex class: 

    global class UpdPrimaryCampaignOnOpty implements Database.Batchable<sObject>,Schedulable{
    
        global String Query;
        global UpdPrimaryCampaignOnOpty(){ 
            query = 'Select Id, contactId, opportunityId,isPrimary from OpportunityContactRole where (createddate = today or lastmodifieddate = today) and  opportunity.CampaignId = null';
        }
        
        global void execute(SchedulableContext SC){
            UpdPrimaryCampaignOnOpty upc =  new UpdPrimaryCampaignOnOpty();
            ID batchprocessid = Database.executeBatch(upc);
        }
        
         global DataBase.QueryLocator start(Database.BatchableContext BC){ 
            return Database.getQueryLocator(query);
        }
        global void execute(Database.BatchableContext BC, List<sObject> scope){
            System.debug('scope size = '+scope.size());
            set<Id> conIds = new Set<Id>();
            Set<Id> optyIds = new Set<Id>();
            Map<Id,Id> optyConMap = new Map<Id,Id>();
            for(sObject s : scope){
                OpportunityContactRole ocr = (OpportunityContactRole)s;
                if(ocr.isPrimary){
                    conIds.add(ocr.contactId);
                    optyIds.add(ocr.opportunityId);
                    optyConMap.put(ocr.OpportunityId, ocr.ContactId);
                }
            }
            System.debug('conIds size = '+conIds.size());
            System.debug('optyIds size = '+optyIds.size());
            System.debug('optyConMap size = '+optyConMap.size());
            
            List<CampaignMember> cmList = [Select id, CampaignId, ContactId, Campaign.createddate from CampaignMember where ContactId IN :conIds];
            System.debug('cmList size = '+cmList.size());
            Map<Id,CampaignMember> contactCampaignMap = new Map<Id,CampaignMember>();
            for(CampaignMember cm : cmList){
                
                if(contactCampaignMap.containsKey(cm.contactId) && cm.Campaign.createddate > contactCampaignMap.get(cm.contactId).Campaign.CreatedDate ){
                    contactCampaignMap.put(cm.contactId, cm);
                }
                else{
                    contactCampaignMap.put(cm.contactId, cm);
                }           
            }
            
            List<Opportunity> optyList = [Select Id, CampaignId from Opportunity where Id IN :optyIds];
            
            for(Opportunity opty : optyList){
                if(optyConMap.containsKey(opty.id) && contactCampaignMap.containsKey(optyConMap.get(opty.Id))){
                    opty.CampaignId = contactCampaignMap.get(optyConMap.get(opty.Id)).CampaignId;
                }        
            }
            
            update optyList;
            
        }
        
        global void finish(Database.BatchableContext BC){
           
       }
            
    }
We have "Location" field on Opportunity with picklist values and we have "Opp_Location__c" field on the account, this trigger displays the values of "Location" field into "Opp_Location__c" field, how to modify the trigger so i can map the same values and not display it more than once? for ex i have picklist value "Hospital" and if the account has 10 opps with same hospital location then i want to display it only one time 


trigger RollupLocation on Opportunity (after insert, after update) { 
  Map<ID, Account > parentOpps = new Map<ID, Account>(); 
  Set<Id> listIds = new Set<Id>();

  for (Opportunity childObj : Trigger.new) {
    listIds.add(childObj.AccountId);
  }

  parentOpps = new Map<Id, Account>([SELECT id, Opp_Location__c ,
                                        (SELECT ID, Location_Type__c  FROM Opportunities) 
                                    FROM Account WHERE ID IN :listIds]);

  List<Account> lstAccount = new List<Account>();

  for(Account acct:parentOpps.values())
  {  
      List<String> strType = new List<String>();
      for(Opportunity opty:acct.Opportunities)
      {
          strType.add(opty.Location_Type__c);
      }
      acct.Opp_Location__c = String.join(strType,',');

  }

  update parentOpps.values();
}
I have the below triggers and test class for them, Trigger-1 has 85% coverage and Trigger-2 has 66%, can anyone please help me in improving code coverage? Highlighted lines in bold which are not covering 

Trigger-1:   

    trigger AccountName_Opp on Opportunity (before insert, before update ){
    
        Map<String, Opportunity> OppMap = new Map<String, Opportunity>();
    
        for(Opportunity opp:Trigger.new)
        {
            OppMap.put(opp.Account_Name__c, opp);
    
        }
    
        List<Account> accLst = [SELECT ID, Name FROM Account where Name in :OppMap.keySet()];
    
        for(Account acct : accLst){
            OppMap.get(acct.Name).AccountId = acct.ID;
        }
    }

Trigger-2: 

    trigger AccountName_Contact on Contact (before insert, before update ){
    
        Set<String> conaccounts = new Set<String>();
    
        for(Contact con:Trigger.new)
        {
            conaccounts.add(con.Account_Name__c);
        }
    
        List<Account> accLst = [SELECT ID, Name FROM Account where Name in :conaccounts];
        System.debug(accLst);
        for(Account acct : accLst){
            for(Contact co : Trigger.new){
                if(co.Account_Name__c == acct.Name)
                    co.accountid = acct.id;

            }        
        }
    
    }

Testclass:
 

    @istest
    public class FFCNAccountName
    {
      static testmethod void myTest()
      {
        Map<String, Opportunity> OppMap = new Map<String, Opportunity>();
        
        Account acc = new Account(Name = 'test', phone = '1234567890');
        insert acc;
        
        Opportunity opp = new Opportunity(SaleType__c = 'new', Name = 'test', AccountId = acc.Id, Amount = 50, CurrencyIsoCode = 'USD');
        insert opp;
        
        Contact con = new Contact( LastName = 'Test2', Email = 'test.user@gmail.com', AccountId = acc.Id );
        insert con;
      }
    }
Can anyone help me with test class for below trigger?

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isafter  && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a
        //criteria to ensure only the appropriate connection record is returned.
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName
             From PartnerNetworkConnection
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Name.contains('US')|| oppRecord.Name.contains('VSI')){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID, Name, Account.Id From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                     LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                         // ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }//for
            
            //Insert record connections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }//if
    }
}
I got this error when i edit the record, how to fix it? Apex trigger AutoforwardOpp caused an unexpected exception, contact your administrator: AutoforwardOpp: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Contact.AccountId: Trigger.AutoforwardOpp: line 91, column 1

Trigger AutoforwardOpp on Opportunity(after insert, after update)
{
    List <PartnerNetworkRecordConnection> prncList;
    List <PartnerNetworkConnection> connectionList;
    Map <ID, PartnerNetworkConnection> connMap;
    Map <ID, ID> oppIdvsAccountIdMap;
    Map<ID, Account> accountWithContactMap;
    
    ID cid;
    String status;
    String connName;

    if(Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)){
            
        connectionList = new List<PartnerNetworkConnection>();
        prncList = new List<PartnerNetworkRecordConnection>();
        
        //This would ideally return multiple active Connections if they exist hence its best you use a 
        //criteria to ensure only the appropriate connection record is returned. 
        connMap = new Map<ID, PartnerNetworkConnection>(
            [Select ID, ConnectionStatus, ConnectionName 
             From PartnerNetworkConnection 
             Where ConnectionStatus = 'Accepted']);
        
        //get connection details        
        for(ID connId :connMap.keySet()){
            cid = connMap.get(connId).ID;
            status = connMap.get(connId).ConnectionStatus;
            connName = connMap.get(connId).ConnectionName;
        }
        
        //Populate a map of Opp Ids and associated Account Ids
        oppIdvsAccountIdMap = new Map<ID, ID>();
        for(Opportunity oppRecord :Trigger.new){
        
            if(oppRecord.Department__c == 'US'){
                    //System.debug('Opp Id: ' + oppRecord.ID + '-> Account Id: ' + oppRecord.AccountId);
                    oppIdvsAccountIdMap.put(oppRecord.ID, oppRecord.AccountId);
            }
        }
        
        //Get associated Accounts and Contacts for every US opportunity if they exist
        if(oppIdvsAccountIdMap.keySet().size() > 0){
        
            accountWithContactMap = new Map<ID, Account>(
                [Select ID, Name,
                    (Select ID,Name From Account.Contacts)
                 From Account
                 Where ID IN :oppIdvsAccountIdMap.values()]);

            //Create PartnerNetworkRecordConnections for sharing the records
            for(ID oppId : oppIdvsAccountIdMap.keySet()){
            
                ID accountId = oppIdvsAccountIdMap.get(oppId);
                
                //Share Opportunity
                prncList.add(new PartnerNetworkRecordConnection(
                    ConnectionId = cid,
                    LocalRecordId = oppId,
                    SendClosedTasks = true,
                    SendOpenTasks = true,
                    SendEmails = true));
                
                //Share Account
                if(oppIdvsAccountIdMap.get(oppId) != null){
                
                    prncList.add(new PartnerNetworkRecordConnection(
                        ConnectionId = cid,
                        LocalRecordId = accountId,
                        SendClosedTasks = true,
                        SendOpenTasks = true,
                        SendEmails = true));
                }
                
                //Share associated Contacts
                if(accountWithContactMap.get(accountId).Contacts != null){
                                   
                    for(Contact contact :accountWithContactMap.get(accountId).Contacts){
                    
                        prncList.add(new PartnerNetworkRecordConnection(
                            ConnectionId = cid,
                            LocalRecordId = contact.ID,
                            ParentRecordId = Contact.AccountId,
                            SendClosedTasks = true,
                            SendOpenTasks = true,
                            SendEmails = true));
                    }
                }
            }//for
            
            //Insert record conneections
            if(!prncList.isEmpty()){
            
                try{
                    insert prncList;
                }
                catch(System.Dmlexception dmlExceptionInstance){
                    System.debug('Record Share Error:' + dmlExceptionInstance.getMessage());
                }
            }
        }//if
    }
}
Right now I am using the below trigger to forward an Opportunity via Salesforce2Salesforce. Is it possible to transfer related contacts along with account?
Trigger Description: Whenever Department is set to "US" then the Opp automatically gets forwarded to Connection


Trigger AutoforwardOpp on Opportunity(after insert, before update)
{
    String UserName = UserInfo.getName();
    String orgName = UserInfo.getOrganizationName();
    List<PartnerNetworkConnection> connectionList = new List<PartnerNetworkConnection>();
    List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>
    ([select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted']);
    List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();

    for(Integer i =0; i< Trigger.size; i++)
    {
        Opportunity opp = Trigger.new[i];
        String oId = opp.Id;
        String accId = opp.AccountId;
        for(PartnerNetworkConnection network : connMap)
        {

            String cid = network.Id;
            String status = network.ConnectionStatus;
            String connName = network.ConnectionName;

            if(opp.Department__c == 'US')
            {
                PartnerNetworkRecordConnection newAccRecord = new PartnerNetworkRecordConnection();
                newAccRecord.ConnectionId = cid;
                newAccRecord.LocalRecordId = accId;
                newAccRecord.SendClosedTasks = true;
                newAccRecord.SendOpenTasks = true;
                newAccRecord.SendEmails = true;
                System.debug('Inserting New Record'+newAccrecord);
                insert newAccrecord;

                PartnerNetworkRecordConnection newOpprecord = new PartnerNetworkRecordConnection();
                newOpprecord.ConnectionId = cid;
                newOpprecord.LocalRecordId = oId;
                newOpprecord.SendClosedTasks = true;
                newOpprecord.SendOpenTasks = true;
                newOpprecord.SendEmails = true;
                System.debug('Inserting New Record'+newOpprecord);
                insert newOpprecord;
            }
        }
    }
}
We have a VF custom button on lead record that sends email to a selected contact but when the email is sent it doesn't shows up on lead activity history, is there any way to track the emails being sent through this button?


Apex class:

    /*Controller to send This lead to any selected Contact */
    
    public class EmailController {
        public Lead leadRecord {get;set;}   
        public String TemplateID {get;set;}
        public String subject { get; set; }
        public String body { get; set; }
        public String htmlBody { get; set; }          
        public EmailTemplate  ET{ get; set; }
        public EmailController(ApexPages.StandardController controller) {
            String lid = '';
            TemplateID = ''; 
            htmlBody ='';
            if(ApexPages.currentPage().getParameters().get('id') != null )
                lid = ApexPages.currentPage().getParameters().get('id');
             system.debug('lidid ' + lid );    
    
            try{             
                leadRecord = [select Status,ID,Contact__c,Name,Company,NumberOfEmployees,Street,City,State,PostalCode,Country,Website,Salutation,FirstName,
                             LastName,Title,Department__c,Email,Phone,MobilePhone,Fax,Product__c,Industry,Specialty__c,Rating,BuyingTimeframe__c,LeadSource,WebFormDetail__c,
                             Description,Marketing_Comments__c from Lead where id = : lid];
                //Change the Template name below.
                ET = [Select ID,HTMLValue,Subject from EmailTemplate  where   name = 'Lead Email' ];            
                if (ET != null){
                    TemplateID  = ET.id;        
                    htmlBody  = ET.HTMLValue ;
                    Subject = ET.Subject;
                    ReplaceTags();   
                }
            }
            catch(Exception e){
                ApexPages.addMessage(new ApexPages.message(ApexPages.severity.Error,e.getMessage()));
            }
        }                  
    
        public void ReplaceTags(){
    
            if(htmlBody.indexOf('{!Lead.Id}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Id}',nullToString(leadRecord.Id));
    
            if(htmlBody.indexOf('{!Lead.Name}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Name}',nullToString(leadRecord.Name));
    
            if(htmlBody.indexOf('{!Lead.Company}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Company}',nullToString(leadRecord.Company));
    
            if(htmlBody.indexOf('{!Lead.NumberOfEmployees}') >-1)
                htmlBody = htmlBody.replace('{!Lead.NumberOfEmployees}',nullToString(String.valueOf(leadRecord.NumberOfEmployees)));
    
            if(htmlBody.indexOf('{!Lead.Address}') >-1){
                String Address = '' ;
                Address =  Address  + nullToString(String.valueOf(leadRecord.Street));
                Address =  Address  + ' ' + nullToString(leadRecord.City);
                Address =  Address  + ','+ nullToString(leadRecord.State);
                Address =  Address  + ' ' + nullToString(leadRecord.PostalCode);
                Address =  Address  + ' ' + nullToString(leadRecord.Country);
                htmlBody = htmlBody.replace('{!Lead.Address}',Address);
    
            }
            if(htmlBody.indexOf('{!Lead.Street}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Street}',nullToString(String.valueOf(leadRecord.Street)));
    
            if(htmlBody.indexOf('{!Lead.City}') >-1)
                htmlBody = htmlBody.replace('{!Lead.City}',nullToString(leadRecord.City));
    
            if(htmlBody.indexOf('{!Lead.State}') >-1)
                htmlBody = htmlBody.replace('{!Lead.State}',nullToString(leadRecord.State));
    
            if(htmlBody.indexOf('{!Lead.PostalCode}') >-1)
               htmlBody = htmlBody.replace('{!Lead.PostalCode}',nullToString(leadRecord.PostalCode));
    
            if(htmlBody.indexOf('{!Lead.Country}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Country}',nullToString(leadRecord.Country));
    
           
            if(htmlBody.indexOf('{!Lead.FirstName} ') >-1)
                htmlBody = htmlBody.replace('{!Lead.FirstName} ',nullToString(leadRecord.FirstName) );
    
            if(htmlBody.indexOf('{!Lead.LastName}') >-1)
                htmlBody = htmlBody.replace('{!Lead.LastName}',nullToString(leadRecord.LastName));
    
            if(htmlBody.indexOf('{!Lead.Title}') >-1)
                htmlBody = htmlBody.replace('{!Lead.Title}',nullToString(leadRecord.Title));
                  
    
        }
        public PageReference send() {
         List<Messaging.SingleEmailMessage> email = new List<Messaging.SingleEmailMessage>();
    
            if(leadRecord.Contact__c == null){
                 ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Please select contact and Try again.'));
                 return null;   
            }
    
            if (TemplateID != null){
                // Query Contact Email ID
                 try{
                    Contact c =  [Select Id,Email,Name from Contact where ID =: leadRecord.Contact__c]; 
                    if (c.Email != null && c.Email != ''){ 
                        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    
                            if(htmlBody.indexOf('{!Contact.Name}') >-1)
                                htmlBody = htmlBody.replace('{!Contact.Name}',nullToString(c.name));
    
                            mail.setTargetObjectId(c.id);
                            mail.setSubject(Subject);
                            mail.setHtmlBody(HtmlBody);
                            mail.setsaveAsActivity(true);                     
                        email.add(mail);
                        Messaging.sendEmail(email);
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Email sent successfully!'));
    
                        leadRecord.Status = 'Tracking';
                        update leadRecord;
                    }
                    else{
                        ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Selected Contact has no Valid Email Address, kindly update the contact and Try again.'));
                        return null;   
                    }
                 }catch(Exception e){}
            }
    
            return new PageReference('/' + leadRecord.id);  
        }
        public String nullToString(String s){
            if (s== null)
                return '';
            else 
                return s;           
        }
        public PageReference cancel(){
            return new PageReference('/' + leadRecord.id);  
        }
    } 

VF Page: <apex:page standardcontroller="Lead" extensions="EmailController" showheader="false">
    <apex:form >
        <apex:pageBlock title="Please select the Contact below">
    
            <br/>    
                <apex:pageMessages />
                <b><apex:outputLabel value="To" for="To"/>:</b><br /> 
                <apex:inputField value="{!leadRecord.Contact__c}" id="To" />
                <br />
                <br />                                
                <b><apex:outputLabel value="Subject" for="Subject"/>:</b><br />     
                <apex:outputText value="{!ET.subject}" id="Subject" />
                <br />
                <br />               
                <apex:inputTextArea value="{!htmlBody}" id="Body"  rows="30" cols="80" richText="true" disabled="true" /> 
                <br /><br /><br />
                <apex:commandButton value="Send Email" action="{!send}" />
                <apex:commandButton value="Cancel & Return" action="{!Cancel}" /> 
        </apex:pageBlock>     
    </apex:form>
</apex:page>

Is it possible to add public calendar to visual forca page with some standard controller and ID?

 

Click to "change button" is very uncomfortable way and I want to just show visualforce page with one click tab.

  • January 06, 2011
  • Like
  • 0