• Robert Goldberg 9
  • NEWBIE
  • 30 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 8
    Questions
  • 16
    Replies
I have a Visualforce search page with a wrapper class, where I want to take the selected results, add them to a list, and then have that list passed to another page.  I cannot compile my current class, which drives the page.  Here's the class:

public with sharing class AllOppsearchClass
{
    public List<Lead> leadList {get; set;}
    public Set<Lead> leadsel {get; set;}
    public List<Opportunity> optyList {get; set;}
    public list<Opportunity> optysel {get; set;}
    public String searchStr {get; set;}


    // lists for the results
    public List<LeadResultWrapper> leadResults {get; set;}
    public List<OpportunityResultWrapper> opportunityResults {get; set;}

    public AllOppsearchClass()
    {

    }
    public void UpdateLeadRouterCommentsLead()
    {

    }
    public void UpdateLeadRouterCommentsOpp()
    {
      
    }
    public AllOppsearchClass(ApexPages.StandardController stdController)
    { }
 
    public void soslDemo_method()
    {
        leadList = New List<Lead>();
        optyList = New List<Opportunity>();

        // instantiate the result lists
        leadResults = new List<LeadResultWrapper>();
        opportunityResults = new List<OpportunityResultWrapper>();

        if(searchStr.length() > 1)
        {
            String searchStr1 = '*'+searchStr+'*';
            String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Email,Owner_Name__c,metro__c,Last_Comment__c,statusname__c,Listing_MLS__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,Listing_Area__c,referral_fee__c,Current_Source__c,Lead_Router_ID__c,Status,Routing_Group__c,Comments_Notes__c,last_activity_subject__c,Potential_Duplicate__c),Opportunity(Id,Name,Account_Email__c,StageName,Opportunity_EMail__c,metro__c,Last_Comment__c,statusname__c,Owner_Name__c,last_update_date__c,date_entered_into_Lead_router__c,Current_Source__c,Listing_Area__c,Comments_Notes__c,listing_amount__c,listing_agent__c,Lead_Router_ID__c,Routing_Group__c,agent__c,Listing_MLS__c,referral_fee__c,last_activity_subject__c,Potential_Duplicate__c)';
            List<List <sObject>> searchList = search.query(searchQuery);
            leadList = ((List<Lead>)searchList[0]);
            optyList = ((List<Opportunity>)searchList[1]);
            if(leadList.size() == 0 && optyList.size() == 0)
            {
                apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
                return;
            }

            // take the contents of the object lists and add them into the result wrapper lists
            for (Lead l : leadList) leadResults.add(new LeadResultWrapper(l));
            for (Opportunity o : optyList) opportunityResults.add(new OpportunityResultWrapper(o));
        }
        else
        {
            apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
            return;
        }
    }

    // to take action on selected leads

    public class LeadResultWrapper
    {
        public Lead l {get; set;}
        public Boolean selectedEh {get; set;}

        public LeadResultWrapper(Lead lIn)
        {
            // assign the record from the inital sosl query row and set checkbox option to FALSE
            l = lIn;
            selectedEh = FALSE;
        }
    }
    public PageReference doSomethingWithLeads()
    {
        for (LeadResultWrapper l : leadResults) // loop through all lead records in search results
        {
            //List<String> leadselec = New List <String>();
            if(l.selectedEh=TRUE) {leadsel.addAll(leadList);}
            List<Lead> leadselec = [SELECT Id FROM Lead WHERE Id In:leadsel];

            {
            ApexPages.StandardController controller = new ApexPages.StandardController(leadselec);
            PageReference MassLRCommentLead = new ApexPages.StandardController(leadselec).view();
            MassLRCommentLead.setRedirect(true);
            return MassLRCommentLead;
            }
        }

        return null;
    }

    public class OpportunityResultWrapper
    {
        public Opportunity o {get; set;}
        public Boolean selectedEh {get; set;}

        public OpportunityResultWrapper(Opportunity oIn)
        {
            // assign the record from the inital sosl query row and set checkbox option to FALSE
            o = oIn;
            selectedEh = FALSE;
        }
    }
        // to take action on selected opportunities
    public PageReference doSomethingWithOpportunities()
    {
        for (OpportunityResultWrapper o : opportunityResults) // loop through all opportunity records in search results
        {
             if(o.selectedEH=TRUE) {optysel.addall(optyList);}
            //PageReference MassLRComment = new ApexPages.StandardController(opportunityResults).view();
            //MassLRComment.setRedirect(true);
            //return MassLRComment;
        }

        return null;
    }

}

And the page:

<apex:page controller="AllOppsearchClass">
    <apex:form >
        <apex:inputtext value="{!searchStr}"></apex:inputtext>
        <apex:commandbutton value="Search in Lead, Opportunity" action="{!soslDemo_method}" rerender="lead,error,oppt" status="actStatusId"></apex:commandbutton>
        <apex:actionstatus id="actStatusId">
        <apex:facet name="start">
            <img src="/img/loading.gif"/>                    
                </apex:facet>
        </apex:actionstatus>
    </apex:form>

 
    <apex:outputpanel title="" id="error">
        <apex:pagemessages ></apex:pagemessages>
    </apex:outputpanel>

    <!-- opportunity results; note that because we've placed the Opportunity record inside of the wrapper, we call down the object hierarchy -->
    <apex:pageblock title="Opportunities" id="oppt">
        <!-- buttons to take action on opportunity results selected -->
        <apex:form >
        <apex:commandButton action="{!URLFOR($Page.MassLRComment, null)}" id="editButton" value="Update Status & Comments" />
</apex:form>
        <apex:pageblocktable value="{!opportunityResults}" var="opty">
            <!-- add a column for each checkbox field -->
            <apex:column >
                <apex:form >
                <apex:inputcheckbox value="{!opty.selectedEh}"></apex:inputcheckbox></apex:form>
            </apex:column>            
            <apex:column value="{!opty.o.Date_Entered_Into_Lead_Router__c}"></apex:column>
            <apex:column value="{!opty.o.Metro__c}"></apex:column>
            <apex:column headervalue="Name"><apex:outputlink value="/{!opty.o.ID}" target="_blank">{!opty.o.Name}</apex:outputlink></apex:column>
            <apex:column value="{!opty.o.Lead_Router_ID__c}"></apex:column>
            <apex:column value="{!opty.o.StageName}"></apex:column>
            <apex:column value="{!opty.o.Agent__c}"></apex:column>     
            <apex:column value="{!opty.o.Account_Email__c}"></apex:column>
            <apex:column value="{!opty.o.Current_Source__c}"></apex:column>
            <apex:column value="{!opty.o.Referral_Fee__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Agent__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Area__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Amount__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_MLS__c}"></apex:column>
            <apex:column value="{!opty.o.Comments_Notes__c}"></apex:column>
            <apex:column value="{!opty.o.Potential_Duplicate__c}"></apex:column>

        </apex:pageblocktable>
    </apex:pageblock>
 
    <!-- lead results; note that because we've placed the Lead record inside of the wrapper, we call down the object hierarchy -->
    <apex:pageblock title="Leads" id="lead">
        <!-- buttons to take action on lead results selected -->
<apex:form >
        <apex:commandButton action="{!URLFOR($Page.MassLRCommentLead, null)}" id="editButton" value="Update Status & Comments" />
</apex:form>
        <apex:pageblocktable value="{!leadResults}" var="lead">
            <!-- add a column for checkbox field -->
            <apex:column ><apex:form >
                <apex:inputcheckbox value="{!lead.selectedEh}"></apex:inputcheckbox>
</apex:form>
            </apex:column>            

            <apex:column value="{!lead.l.Date_Entered_Into_Lead_Router__c}"></apex:column>
            <apex:column value="{!lead.l.Metro__c}"></apex:column>
            <apex:column headervalue="Name"><apex:outputlink value="/{!lead.l.ID}" target="_blank">{!lead.l.Name}</apex:outputlink></apex:column>
            <apex:column value="{!lead.l.Lead_Router_ID__c}"></apex:column>
            <apex:column value="{!lead.l.Status}"></apex:column>
            <apex:column value="{!lead.l.Routing_Group__c}"></apex:column>
            <apex:column value="{!lead.l.email}"></apex:column>
            <apex:column value="{!lead.l.Current_Source__c}"></apex:column>
            <apex:column value="{!lead.l.Referral_Fee__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Agent__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Area__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Amount__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_MLS__c}"></apex:column>
            <apex:column value="{!lead.l.Comments_Notes__c}"></apex:column>
            <apex:column value="{!lead.l.Potential_Duplicate__c}"></apex:column>                                                
                        
        </apex:pageblocktable>
    </apex:pageblock>
</apex:page>
I have an issue that I would love some advice on.  I have a working button on both Leads & Opportunities, that sends a webservice call to an external system, and then responds accordingly to create events on the related record.

Instead of having this button work on demand, my users want this to fire upon page load, so I would like to insert the code to run this webservice call upon a page load of a simple Visualforce page.  So, as I tried to do that, I'm getting an error: Content cannot be displayed: List has no rows for assignment to SObject.  I'm unsure where the assignment is failing, or if I'm calling the wrong thing.  Any advice?

Here's my page:

<apex:page standardcontroller="Opportunity" extensions="LeadRouter_GetHistory,customActivityHistoryController" action="{!GetLeadCallLogs}"> <apex:outputText style="color: blue; float:right; font-weight: bold" value="{!showMsg}" rendered="{!Msgid}"/>
</apex:page>

And my Controllers:
1:
public class customActivityHistoryController
{
    
    public String taskId {get; set;}
    public String prefix {get; set;}
    public String showMsg {get; set;}
    public boolean  Msgid {get; set;}
    public Id recordId {get; set;}
    private String sObjName {get; set;}
    private string leadRouterId;
    private string LRUserId;
    private datetime LRDate;
   
        
    public customActivityHistoryController (ApexPages.StandardController controller )
    {
        // get the record id. It could be any sobject type.
        recordId = controller.getId();
       
    }
    
    public customActivityHistoryController ( )
    {       
        // get the record id. It could be any sobject type.
        recordId = ApexPages.currentPage().getParameters().get('id');
    }
    
    
    public void getLeadHistory()
    {
        init('History');
        LeadRouter leadRouter = new LeadRouter();
        leadRouter.GetLeadHistory(leadRouterId, LRUserId , LRDate);
       
        getActivities();
    }
    
    public void GetLeadCallLogs()
    {
        init('CallLog');
        LeadRouter leadRouter = new LeadRouter();
        LeadRouter_GetHistory.getCalls(leadRouterId, recordId);
        getActivities();
    }
    
public void init(string typeOfLog)
    {
        // get the object name according to the id
         sObjName = recordId.getSObjectType().getDescribe().getName();
         prefix = recordId.getSObjectType().getDescribe().getKeyPrefix();
        
        if ( sObjName.equalsIgnoreCase('lead') )
        {            
            Lead lead = [select Id, LR_User_ID__c, Last_LeadRouter_CallLog_Date__c, Last_LR_History_Check__c, Last_LeadRouter_History_Date__c, Lead_Router_ID__c, Date_Entered_Into_Lead_Router__c, CreatedDate from Lead where Id = :recordId ];
            leadRouterId=lead.Lead_Router_ID__c;
            System.debug('>>>>> Lead.Id: ' + lead.id);
            LRUserId    =lead.LR_User_ID__c ;
            if (typeOfLog=='History')
                LRDate      = lead.Last_LeadRouter_History_Date__c;
                        if (lead.Last_LeadRouter_CallLog_Date__c ==NULL )
        {
        Showmsg='No Lead Router Calling History' ;  
         Msgid =true;
            }
         //   else if (typeOfLog=='CallLog')
         //     LRDate      = lead.Last_LeadRouter_CallLog_Date__c;
         //   if (LRDate == null && lead.Date_Entered_Into_Lead_Router__c != null)
         //       LRDate = lead.Date_Entered_Into_Lead_Router__c;
         //   else
         //       LRDate = lead.CreatedDate;
            
            
        } else if ( sObjName.equalsIgnoreCase('opportunity')){
            Opportunity opportunity = [select Id, LR_User_ID__c, Last_LeadRouter_CallLog_Date__c, Last_LR_History_Check__c, Last_LeadRouter_History_Date__c, Lead_Router_ID__c, Date_Entered_Into_Lead_Router__c, CreatedDate from Opportunity where Id = :recordId];
            leadRouterId=opportunity.Lead_Router_ID__c;
            LRUserId    = opportunity.LR_User_ID__c ;
              if (typeOfLog=='History')
                LRDate      = opportunity.Last_LeadRouter_History_Date__c;
                        if (opportunity.Last_LeadRouter_CallLog_Date__c ==NULL )
        {
        Showmsg='No Lead Router Calling History' ;  
         Msgid =true;
            }            
        //    else if (typeOfLog=='CallLog')
        //      LRDate      = opportunity.Last_LeadRouter_CallLog_Date__c;
        //    if (LRDate == null && opportunity.Date_Entered_Into_Lead_Router__c != null)
        //        LRDate = opportunity.Date_Entered_Into_Lead_Router__c;
        //    else
        //        LRDate = opportunity.CreatedDate;
            
        }
        System.debug('>>>>> LRDate: ' + LRDate);
       
    }
    
    public List<ActivityHistory> getActivities()
    {
        
        //Build a SOQL to get the activities related to the sObject type         
        string query  = 'Select Id, (Select Id, Subject, ownerId, Owner.Name, who.Name, ActivityDate, lastModifiedDate, isTask From ActivityHistories order by  lastModifiedDate desc) ' +
                        'from  ' + sObjName +
                        ' where Id = :recordId ';
        
        List<ActivityHistory> result = new List<ActivityHistory>();
        
        
        // get the activities
        list<sObject> activities = database.query(query);
        
        system.debug(activities);
        
        for(sObject l : activities )
        {
            for(sObject ah : l.getSObjects('ActivityHistories') ) {
                result.add((ActivityHistory)ah);
            }
        }
        
        return result;
        
    }
    
    
    public PageReference editRecord(){
        String url = '/';
        url += taskId;
        url += '/e?';
        
        return new PageReference(url).setRedirect(true);
    }
    
    public PageReference deleteRecord(){
        delete [Select Id
                From event
                Where Id = :taskId];
        
        return null;
    }
    

}

2:
global class LeadRouter_GetHistory {

    public Id recordId {get; set;}
    public Opportunity currentOpportunity;
    public LeadRouter_GetHistory (ApexPages.StandardController controller )
    {
        // get the record id. It could be any sobject type.
        recordId = controller.getId();
       
    }
    webService static string getHistory(String entity, string eid){
        
        if (entity == 'Opportunity') {
            Opportunity o = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c from Opportunity where Id = :eid];
            //if (!string.isBlank(o.Lead_Router_ID__c)) {
                LeadRouter.GetLeadHistoryInfo(o.Lead_Router_ID__c, o.LR_User_ID__c, o.Last_LeadRouter_History_Date__c);
            //}
        } else {
            Lead l = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c from Lead where Id = :eid];
            //if (!string.isBlank(l.Lead_Router_ID__c)) {
                LeadRouter.GetLeadHistoryInfo(l.Lead_Router_ID__c, l.LR_User_ID__c, l.Last_LeadRouter_History_Date__c);
            //}
        }
        return eid;
    }
    
    webService static string getCalls(String entity, string eid){
        
        if (entity == 'Opportunity') {
            Opportunity o = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c from Opportunity where Id = :eid];
            //if (!string.isBlank(o.Lead_Router_ID__c)) {
                LeadRouter.GetLeadCallLogsInfo(o.Lead_Router_ID__c, o.Last_LeadRouter_CallLog_Date__c);
            //}
        } else {
            Lead l = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c from Lead where Id = :eid];
            //if (!string.isBlank(l.Lead_Router_ID__c)) {         
                LeadRouter.GetLeadCallLogsInfo(l.Lead_Router_ID__c, l.Last_LeadRouter_CallLog_Date__c);
            //}
        }
        return eid;
    }
    
    public static void test(String entity, string eid){
        if (entity == 'Opportunity') {
            Opportunity o = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c, Last_LR_History_Check__c from Opportunity where Id = :eid];
            o.Last_LR_History_Check__c = DateTime.now();
            update o;
            Event ev = new Event();
            ev.WhatId = o.ID;
            ev.StartDateTime = DateTime.now();
            ev.ActivityDateTime = DateTime.now();
            ev.Subject = 'LeadRouter Test Activity';
            ev.Description = 'LeadRouter Test Activity completed';      
            ev.DurationInMinutes = 0;
            ev.runSubjTrigger__c = false;//so trigger doesn't run on it
            insert ev;
            //}
        } else {
            Lead l = [Select Id, Lead_Router_ID__c, LR_User_ID__c, Last_LeadRouter_History_Date__c, Last_LeadRouter_CallLog_Date__c, Last_LR_History_Check__c from Lead where Id = :eid];
            l.Last_LR_History_Check__c = DateTime.now();
            update l;
            Event ev = new Event();
            ev.WhoId = l.ID;
            ev.StartDateTime = DateTime.now();
            ev.ActivityDateTime = DateTime.now();
            ev.Subject = 'LeadRouter Test Activity';
            ev.Description = 'LeadRouter Test Activity completed';      
            ev.DurationInMinutes = 0;
            ev.runSubjTrigger__c = false;//so trigger doesn't run on it
            insert ev;
        }
        
    }
}
I've written a trigger on a custom object (Agent__c), for when a value (is_active__c) changes to false, that it will look into that custom object, and then see if that agent is active somewhere else.  If so, it should bring back a string and update a field on the original record.

However, I cannot get it to fire, no matter what I do.

Here is the code:

trigger Inactive_Active on Agent__c (before insert, before update) {
    
Set<String> MAKs = new Set<String>();
  for(Agent__c X : trigger.new){
      if(X.Is_Active__c!=true){MAKs.add(X.Modified_Anchor_Key__c);}}
                               
  Map <String, String> AGMAP = new Map <String, String>();
  for (Agent__c AT: [SELECT Modified_Anchor_Key__c, Agent_ID__c
                        from Agent__c
                        Where Modified_Anchor_Key__c IN: MAKs and Is_Active__c=true]){AGMAP.put(AT.Modified_Anchor_Key__c, AT.Agent_ID__c);
         }
    for(Agent__c X: trigger.new){if(AGMAP.containskey(X.Modified_Anchor_Key__c)) X.Active_Agent_ID__c=AGMAP.get(X.Agent_Id__c);}
      }
I have a working Visualforce page and controller, that searches both Leads & Opportunities for a specific email address, and displays fields if there are any results.

I have been asked by our business department to make a change, adding checkboxes and radio buttons to the page.

I have no idea how I might begin doing this.  Does anyone have any ideas?

Here is the controller:

Public with sharing class AllOppsearchClass{
 Public List<Lead>leadList{get;set;}
 Public List<Opportunity>optyList{get;set;}
   Public String searchStr{get;set;}
   Public AllOppsearchClass(){
   }
     public AllOppsearchClass(ApexPages.StandardController stdController){}
 
    Public void soslDemo_method(){
       leadList = New List<Lead>();
   optyList = New List<Opportunity>();

        
   
   if(searchStr.length() > 1){
   String searchStr1 = '*'+searchStr+'*';
   String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Owner_Name__c,Email,metro__c,Last_Comment__c,statusname__c,Listing_MLS__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,referral_fee__c,last_activity_subject__c),Opportunity(Id,Name,Account_Email__c,Opportunity_EMail__c,metro__c,Last_Comment__c,statusname__c,Owner_Name__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,agent__c,referral_fee__c,last_activity_subject__c)';
   List<List <sObject>> searchList = search.query(searchQuery);
   leadList = ((List<Lead>)searchList[0]);
      optyList = ((List<Opportunity>)searchList[1]);
   if(leadList.size() == 0 && optyList.size() == 0){
       apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
       return;
   }
   }
   else{
   apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
   return;
   }
  }
}

And the Visualforce page:

<apex:page standardcontroller="Lead" extensions="AllOppsearchClass">
  <apex:form >
  <apex:inputText value="{!searchStr}"/>
    <apex:commandButton value="Search in Lead, Opportunity" action="{!soslDemo_method}"                reRender="lead,error,oppt" status="actStatusId"/>
    <apex:actionStatus id="actStatusId">
                <apex:facet name="start" >
                    <img src="/img/loading.gif"/>                    
                </apex:facet>
    </apex:actionStatus>
  </apex:form>
 
    <apex:outputPanel title="" id="error">
     <apex:pageMessages ></apex:pageMessages>
     </apex:outputPanel>

     <apex:pageBlock title="Opportunities" id="oppt">
    <apex:pageblockTable value="{!optyList}" var="opty">
     <apex:column headervalue="Name"><apex:outputLink value="/{!opty.ID}" target="_blank">{!opty.name}</apex:outputLink></apex:column>
     <apex:column value="{!opty.Account_Email__c}"/>
     <apex:column value="{!opty.Metro__c}"/>
     <apex:column value="{!opty.Owner_Name__c}"/>
     <apex:column value="{!opty.StatusName__c}"/>
     <apex:column value="{!opty.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!opty.Last_Update_Date__c}"/>     
     <apex:column value="{!opty.Listing_Amount__c}"/>
     <apex:column value="{!opty.Listing_Agent__c}"/>
     <apex:column value="{!opty.Agent__c}"/>
     <apex:column value="{!opty.Referral_Fee__c}"/>
     <apex:column value="{!opty.Last_Comment__c}"/>


       </apex:pageblockTable>
    </apex:pageBlock>
 
    <apex:pageBlock title="Leads" id="lead">
    <apex:pageblockTable value="{!leadList }" var="lead">
     <apex:column headervalue="Name"><apex:outputLink value="/{!lead.ID}" target="_blank">{!lead.name}</apex:outputLink></apex:column>
     <apex:column value="{!lead.email}"/>
     <apex:column value="{!lead.Metro__c}"/>
     <apex:column value="{!lead.Owner_Name__c}"/>
     <apex:column value="{!lead.StatusName__c}"/>
     <apex:column value="{!lead.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!lead.Last_Update_Date__c}"/>
     <apex:column value="{!lead.Listing_Amount__c}"/>
     <apex:column value="{!lead.Listing_MLS__c}"/>
     <apex:column value="{!lead.Listing_Agent__c}"/>
     <apex:column value="{!lead.Referral_Fee__c}"/>
     <apex:column value="{!lead.Last_Comment__c}"/>


 </apex:pageblockTable>
    </apex:pageBlock>
</apex:page>
I have created a Visualforce page with a custom controller that is essentially a search page that I've embedded within the Lead page.  It gives my users the ability to quickly search for duplicates without leaving the page.  The issue is, I'm trying to figure out how to prepopulate the search, so they don't have to copy the email address to the search bar.

Here's the Controller:

Public with sharing class LeadOppsearchclas{
 Public List<Lead>leadList{get;set;}
 Public List<Opportunity>optyList{get;set;}
   Public String searchStr{get;set;}
   Public LeadOppsearchclas(){
   }
 
 public LeadOppsearchclas(ApexPages.StandardController stdController){
 }
 
    Public void soslDemo_method(){
       leadList = New List<Lead>();
   optyList = New List<Opportunity>();
   
   if(searchStr.length() > 1){
   String searchStr1 = '*'+searchStr+'*';
   String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Email,metro__c,statusname__c,Listing_MLS__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,referral_fee__c,last_activity_subject__c),Opportunity(Id,Name,Account_Email__c,Opportunity_EMail__c,metro__c,statusname__c,Owner_Name__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,agent__c,referral_fee__c,last_activity_subject__c)';
   List<List <sObject>> searchList = search.query(searchQuery);
   leadList = ((List<Lead>)searchList[0]);
      optyList = ((List<Opportunity>)searchList[1]);
   if(leadList.size() == 0 && optyList.size() == 0){
       apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
       return;
   }
   }
   else{
   apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
   return;
   }
  }
}

And the Visualforce Page:

<apex:page standardcontroller="Lead" extensions="LeadOppsearchclas">
  <apex:form >
  <apex:inputText value="{!searchStr}"/>
    <apex:commandButton value="Search in Lead, Opportunity" action="{!soslDemo_method}"                reRender="lead,error,oppt" status="actStatusId"/>
    <apex:actionStatus id="actStatusId">
                <apex:facet name="start" >
                    <img src="/img/loading.gif"/>                    
                </apex:facet>
    </apex:actionStatus>
  </apex:form>
 
    <apex:outputPanel title="" id="error">
     <apex:pageMessages ></apex:pageMessages>
     </apex:outputPanel>
 
 <apex:pageBlock title="Opportunities" id="oppt">
    <apex:pageblockTable value="{!optyList}" var="opty">
     <apex:column headervalue="Name"><apex:outputLink value="/{!opty.ID}" target="_blank">{!opty.name}</apex:outputLink></apex:column>
     <apex:column value="{!opty.Account_Email__c}"/>
     <apex:column value="{!opty.Metro__c}"/>
     <apex:column value="{!opty.Owner_Name__c}"/>
     <apex:column value="{!opty.StatusName__c}"/>
     <apex:column value="{!opty.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!opty.Listing_Amount__c}"/>
     <apex:column value="{!opty.Listing_Agent__c}"/>
     <apex:column value="{!opty.Agent__c}"/>
     <apex:column value="{!opty.Referral_Fee__c}"/>
     <apex:column value="{!opty.Last_Activity_Subject__c}"/>


       </apex:pageblockTable>
    </apex:pageBlock>
 
    <apex:pageBlock title="Leads" id="lead">
    <apex:pageblockTable value="{!leadList }" var="lead">
     <apex:column headervalue="Name"><apex:outputLink value="/{!lead.ID}" target="_blank">{!lead.name}</apex:outputLink></apex:column>
     <apex:column value="{!lead.email}"/>
     <apex:column value="{!lead.Metro__c}"/>
     <apex:column value="{!lead.StatusName__c}"/>
     <apex:column value="{!lead.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!lead.Listing_Amount__c}"/>
     <apex:column value="{!lead.Listing_MLS__c}"/>
     <apex:column value="{!lead.Listing_Agent__c}"/>
     <apex:column value="{!lead.Referral_Fee__c}"/>
     <apex:column value="{!lead.Last_Activity_Subject__c}"/>


 </apex:pageblockTable>
    </apex:pageBlock>
</apex:page>
I've spent the last 2 days trying to make some sense of this, and it's killing me.  We have a process wherein leads can either be (1) created with a unique identifier and then are auto-converted (a process which works fine) or (2) are updated after creation (could be hours or days later) with information from our external system, that adds a unique identifier.

I am trying to write a trigger that will recognize this change, and then subsequently convert the lead.

Tests fine, works in sandbox.  In production, I get this error:

Lead DetailError:Apex trigger AgentAdded caused an unexpected exception, contact your administrator: AgentAdded: execution of AfterUpdate caused by: System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00Qo000000J8ITAEA3; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: [] (System Code) : []: Trigger.AgentAdded: line 21, column 1

If anyone can advise on how I should update my trigger, it would be a massive help.  My trigger & test class are below.  Thanks!

Trigger:

Trigger AgentAdded on Lead (after insert, after update) {
LeadStatus convertStatus = [
select MasterLabel
from LeadStatus
where IsConverted = true
limit 1
];
List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
 
for (Lead lead: Trigger.new) {
if (!lead.isConverted && Lead.Agent_ID__c!='0' && Lead.Agent_ID__c !=NULL && Lead.Manually_Routed__c!='TRUE' && Lead.Auto_Assigned__c==FALSE && Lead.Auto_Route__c!='TRUE')
{Database.LeadConvert lc = new Database.LeadConvert();
String oppName = lead.Name;
lc.setLeadId(lead.Id);
lc.setOpportunityName(oppName);
lc.setConvertedStatus(convertStatus.MasterLabel);
leadConverts.add(lc);}
}
 
if (!leadConverts.isEmpty()) {
List<Database.LeadConvertResult> lcr = Database.convertLead(leadConverts);
}
}

TestClass:

@IsTest
private class AgentAddTest {
private static Integer LEAD_COUNT = 0;
private static Lead createLead() {
LEAD_COUNT += 1;
return new Lead(
FirstName = '_unittest_firstname_: ' + LEAD_COUNT,
LastName = '_unittest_lastname_: ' + LEAD_COUNT,
Metro__c='New Jersey'+ LEAD_COUNT,
Status = 'Unread'
);
}
public static void makeFreeTrial(Lead lead) {
lead.Agent_Added__c = TRUE;
lead.agent_id__c='100345678';
}
public static List<Lead> fetchLeads(Set<Id> ids) {
return [
select isConverted
from Lead
where Id in :ids
];
}
public static testMethod void trialConvert() {
Lead testLead = createLead();
makeFreeTrial(testLead);
 
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(results.get(0).isConverted, 'The lead should have been converted since it was a "Free Trail"');
}
 
public static testMethod void nonTrialNoConvert() {
Lead testLead = createLead();
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(!results.get(0).isConverted, 'The lead should not have been converted since it was not a "Free Trial"');
}
public static testMethod void bulkTest() {
List<Lead> shouldBeConverted = new List<Lead>();
List<Lead> shouldNotBeConverted = new List<Lead>();
for (Integer i = 0; i < 50; i++) {
Lead testLeadNonConvert = createLead();
Lead testLeadConvert = createLead();
makeFreeTrial(testLeadConvert);
shouldBeConverted.add(testLeadConvert);
shouldNotBeConverted.add(testLeadNonConvert);
}
List<Lead> toInsert = new List<Lead>();
toInsert.addAll(shouldBeConverted);
toInsert.addAll(shouldNotBeConverted);
Test.startTest();
insert toInsert;
Test.stopTest();
Map<Id, Lead> expectedConversions = new Map<Id, Lead>(shouldBeConverted);
Map<Id, Lead> expectedNonConversions = new Map<Id, Lead>(shouldNotBeConverted);
Set<Id> leadIds = new Set<Id>();
leadIds.addAll(expectedConversions.keySet());
leadIds.addAll(expectedNonConversions.keySet());
for (Lead result: fetchLeads(leadIds)) {
if (expectedConversions.containsKey(result.Id)) {
System.assert(result.isConverted, 'This lead should have been converted ' + result);
expectedConversions.remove(result.Id);
} else if (expectedNonConversions.containsKey(result.Id)) {
System.assert(!result.isConverted, 'This lead should not have been converted ' + result);
expectedNonConversions.remove(result.Id);
} else {
System.assert(false, 'We got a Lead we did not expect to get back ' + result);
}
}
System.assert(expectedConversions.isEmpty(), 'We did not get back all the converted leads we expected');
System.assert(expectedNonConversions.isEmpty(), 'We did not get back all the non converted leads we expected');
}
}
I have a working trigger that updates a lookup field from a zipcode object when the zipcode name = the listing zip code on the lead.  However, I need to add an additional restriction, where the metro__c field on the lead = the metro__c field on the zip code table, and I'm not sure how to do this.  How would I add this restriction?

The working trigger is below:

trigger UpdateListingZip on Lead (before insert, before update) {
    Set<String> ListingZips = new Set<String>();

    for( Lead l : trigger.new ) {
        if( l.listing_zip_code__c != null && l.LAG_Offered__c!=TRUE && l.DTA_Lead__c !=TRUE) {
            ListingZips.add( l.listing_zip_code__c );
                        
 }
    }            

        // Now we have a set of unique zipcodes we want to verify, time to look them up.
    // I plan to build a map of the "match field" -> "full reference object"

    Map<String, zip_codes__c> MatchZips = new Map<String, zip_codes__c>();

    for(zip_codes__c obj : [SELECT  Id,
                                           zipcode__c
                                            FROM    Zip_Codes__c
                                            WHERE     zipcode__c IN :ListingZips] ) {MatchZips.put( obj.zipcode__c, obj );
    }
    // We have all the reference data we need, last loop on the each lead

    for( Lead l : trigger.new ) {

        if( l.listing_zip_code__c != null ) { // there IS a countrylist entry to deal with... so...

            if( MatchZips.containsKey(l.listing_zip_code__c) ) { l.Zip_Code_Lookup__c = MatchZips.get(l.listing_zip_check__c).ID; }}
}
}
I've got a number of lookup fields that I need to populate based on an ID field that will be passed over from our source system.  The custom object is Agent__c.

I've been able to get to 83% coverage (which I know is fine - but we're going to have hundreds of leads processing via this every day - and I want to make sure it won't fail).

Any help/advice would be hugely appreciated.

Here's my trigger:

trigger AgentAssignmentLead on Lead (before insert, before update) {
    Set <String> AgentIDs = new Set <String>();
    for (Lead l : trigger.new) {
        if (l.Agent_ID__c !=NULL) {
            AgentIDs.add (l.Agent_ID__c );
        }
    }
//now we have our list of agent IDs that we want to check against.
//We will build a map of the "match" field

    Map<String, Agent__c> Agents = new map <String, Agent__C>();
    for (Agent__c obj: [SELECT ID,
                        Agent_ID__c
                        from Agent__c
                        Where Agent_ID__C in :AgentIDs]){
                            Agents.put(obj.Agent_ID__c, obj);
                        }
    for (Lead l : trigger.new) {
        if (l.Agent_ID__c !=NULL){
            if (Agents.containsKey(l.Agent_ID__c))
                l.Agent__c=Agents.get(l.Agent_ID__c).ID;
        }
    }
}


And my test class:

@istest
public with sharing class AgentLeadTest {
    public static void UpdateAgent()
    {
        //create the new lead
        Lead Lead = new Lead ();
        Lead.LastName='Adrian';
        Lead.FirstName='Tooms';
        Lead.status='Unread';
        Lead.Metro__c='New Jersey';
        Lead.Agent_ID__c='100683628';
            test.startTest();
        insert Lead;
    }

}
I have a Visualforce search page with a wrapper class, where I want to take the selected results, add them to a list, and then have that list passed to another page.  I cannot compile my current class, which drives the page.  Here's the class:

public with sharing class AllOppsearchClass
{
    public List<Lead> leadList {get; set;}
    public Set<Lead> leadsel {get; set;}
    public List<Opportunity> optyList {get; set;}
    public list<Opportunity> optysel {get; set;}
    public String searchStr {get; set;}


    // lists for the results
    public List<LeadResultWrapper> leadResults {get; set;}
    public List<OpportunityResultWrapper> opportunityResults {get; set;}

    public AllOppsearchClass()
    {

    }
    public void UpdateLeadRouterCommentsLead()
    {

    }
    public void UpdateLeadRouterCommentsOpp()
    {
      
    }
    public AllOppsearchClass(ApexPages.StandardController stdController)
    { }
 
    public void soslDemo_method()
    {
        leadList = New List<Lead>();
        optyList = New List<Opportunity>();

        // instantiate the result lists
        leadResults = new List<LeadResultWrapper>();
        opportunityResults = new List<OpportunityResultWrapper>();

        if(searchStr.length() > 1)
        {
            String searchStr1 = '*'+searchStr+'*';
            String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Email,Owner_Name__c,metro__c,Last_Comment__c,statusname__c,Listing_MLS__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,Listing_Area__c,referral_fee__c,Current_Source__c,Lead_Router_ID__c,Status,Routing_Group__c,Comments_Notes__c,last_activity_subject__c,Potential_Duplicate__c),Opportunity(Id,Name,Account_Email__c,StageName,Opportunity_EMail__c,metro__c,Last_Comment__c,statusname__c,Owner_Name__c,last_update_date__c,date_entered_into_Lead_router__c,Current_Source__c,Listing_Area__c,Comments_Notes__c,listing_amount__c,listing_agent__c,Lead_Router_ID__c,Routing_Group__c,agent__c,Listing_MLS__c,referral_fee__c,last_activity_subject__c,Potential_Duplicate__c)';
            List<List <sObject>> searchList = search.query(searchQuery);
            leadList = ((List<Lead>)searchList[0]);
            optyList = ((List<Opportunity>)searchList[1]);
            if(leadList.size() == 0 && optyList.size() == 0)
            {
                apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
                return;
            }

            // take the contents of the object lists and add them into the result wrapper lists
            for (Lead l : leadList) leadResults.add(new LeadResultWrapper(l));
            for (Opportunity o : optyList) opportunityResults.add(new OpportunityResultWrapper(o));
        }
        else
        {
            apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
            return;
        }
    }

    // to take action on selected leads

    public class LeadResultWrapper
    {
        public Lead l {get; set;}
        public Boolean selectedEh {get; set;}

        public LeadResultWrapper(Lead lIn)
        {
            // assign the record from the inital sosl query row and set checkbox option to FALSE
            l = lIn;
            selectedEh = FALSE;
        }
    }
    public PageReference doSomethingWithLeads()
    {
        for (LeadResultWrapper l : leadResults) // loop through all lead records in search results
        {
            //List<String> leadselec = New List <String>();
            if(l.selectedEh=TRUE) {leadsel.addAll(leadList);}
            List<Lead> leadselec = [SELECT Id FROM Lead WHERE Id In:leadsel];

            {
            ApexPages.StandardController controller = new ApexPages.StandardController(leadselec);
            PageReference MassLRCommentLead = new ApexPages.StandardController(leadselec).view();
            MassLRCommentLead.setRedirect(true);
            return MassLRCommentLead;
            }
        }

        return null;
    }

    public class OpportunityResultWrapper
    {
        public Opportunity o {get; set;}
        public Boolean selectedEh {get; set;}

        public OpportunityResultWrapper(Opportunity oIn)
        {
            // assign the record from the inital sosl query row and set checkbox option to FALSE
            o = oIn;
            selectedEh = FALSE;
        }
    }
        // to take action on selected opportunities
    public PageReference doSomethingWithOpportunities()
    {
        for (OpportunityResultWrapper o : opportunityResults) // loop through all opportunity records in search results
        {
             if(o.selectedEH=TRUE) {optysel.addall(optyList);}
            //PageReference MassLRComment = new ApexPages.StandardController(opportunityResults).view();
            //MassLRComment.setRedirect(true);
            //return MassLRComment;
        }

        return null;
    }

}

And the page:

<apex:page controller="AllOppsearchClass">
    <apex:form >
        <apex:inputtext value="{!searchStr}"></apex:inputtext>
        <apex:commandbutton value="Search in Lead, Opportunity" action="{!soslDemo_method}" rerender="lead,error,oppt" status="actStatusId"></apex:commandbutton>
        <apex:actionstatus id="actStatusId">
        <apex:facet name="start">
            <img src="/img/loading.gif"/>                    
                </apex:facet>
        </apex:actionstatus>
    </apex:form>

 
    <apex:outputpanel title="" id="error">
        <apex:pagemessages ></apex:pagemessages>
    </apex:outputpanel>

    <!-- opportunity results; note that because we've placed the Opportunity record inside of the wrapper, we call down the object hierarchy -->
    <apex:pageblock title="Opportunities" id="oppt">
        <!-- buttons to take action on opportunity results selected -->
        <apex:form >
        <apex:commandButton action="{!URLFOR($Page.MassLRComment, null)}" id="editButton" value="Update Status & Comments" />
</apex:form>
        <apex:pageblocktable value="{!opportunityResults}" var="opty">
            <!-- add a column for each checkbox field -->
            <apex:column >
                <apex:form >
                <apex:inputcheckbox value="{!opty.selectedEh}"></apex:inputcheckbox></apex:form>
            </apex:column>            
            <apex:column value="{!opty.o.Date_Entered_Into_Lead_Router__c}"></apex:column>
            <apex:column value="{!opty.o.Metro__c}"></apex:column>
            <apex:column headervalue="Name"><apex:outputlink value="/{!opty.o.ID}" target="_blank">{!opty.o.Name}</apex:outputlink></apex:column>
            <apex:column value="{!opty.o.Lead_Router_ID__c}"></apex:column>
            <apex:column value="{!opty.o.StageName}"></apex:column>
            <apex:column value="{!opty.o.Agent__c}"></apex:column>     
            <apex:column value="{!opty.o.Account_Email__c}"></apex:column>
            <apex:column value="{!opty.o.Current_Source__c}"></apex:column>
            <apex:column value="{!opty.o.Referral_Fee__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Agent__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Area__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_Amount__c}"></apex:column>
            <apex:column value="{!opty.o.Listing_MLS__c}"></apex:column>
            <apex:column value="{!opty.o.Comments_Notes__c}"></apex:column>
            <apex:column value="{!opty.o.Potential_Duplicate__c}"></apex:column>

        </apex:pageblocktable>
    </apex:pageblock>
 
    <!-- lead results; note that because we've placed the Lead record inside of the wrapper, we call down the object hierarchy -->
    <apex:pageblock title="Leads" id="lead">
        <!-- buttons to take action on lead results selected -->
<apex:form >
        <apex:commandButton action="{!URLFOR($Page.MassLRCommentLead, null)}" id="editButton" value="Update Status & Comments" />
</apex:form>
        <apex:pageblocktable value="{!leadResults}" var="lead">
            <!-- add a column for checkbox field -->
            <apex:column ><apex:form >
                <apex:inputcheckbox value="{!lead.selectedEh}"></apex:inputcheckbox>
</apex:form>
            </apex:column>            

            <apex:column value="{!lead.l.Date_Entered_Into_Lead_Router__c}"></apex:column>
            <apex:column value="{!lead.l.Metro__c}"></apex:column>
            <apex:column headervalue="Name"><apex:outputlink value="/{!lead.l.ID}" target="_blank">{!lead.l.Name}</apex:outputlink></apex:column>
            <apex:column value="{!lead.l.Lead_Router_ID__c}"></apex:column>
            <apex:column value="{!lead.l.Status}"></apex:column>
            <apex:column value="{!lead.l.Routing_Group__c}"></apex:column>
            <apex:column value="{!lead.l.email}"></apex:column>
            <apex:column value="{!lead.l.Current_Source__c}"></apex:column>
            <apex:column value="{!lead.l.Referral_Fee__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Agent__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Area__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_Amount__c}"></apex:column>
            <apex:column value="{!lead.l.Listing_MLS__c}"></apex:column>
            <apex:column value="{!lead.l.Comments_Notes__c}"></apex:column>
            <apex:column value="{!lead.l.Potential_Duplicate__c}"></apex:column>                                                
                        
        </apex:pageblocktable>
    </apex:pageblock>
</apex:page>
I've written a trigger on a custom object (Agent__c), for when a value (is_active__c) changes to false, that it will look into that custom object, and then see if that agent is active somewhere else.  If so, it should bring back a string and update a field on the original record.

However, I cannot get it to fire, no matter what I do.

Here is the code:

trigger Inactive_Active on Agent__c (before insert, before update) {
    
Set<String> MAKs = new Set<String>();
  for(Agent__c X : trigger.new){
      if(X.Is_Active__c!=true){MAKs.add(X.Modified_Anchor_Key__c);}}
                               
  Map <String, String> AGMAP = new Map <String, String>();
  for (Agent__c AT: [SELECT Modified_Anchor_Key__c, Agent_ID__c
                        from Agent__c
                        Where Modified_Anchor_Key__c IN: MAKs and Is_Active__c=true]){AGMAP.put(AT.Modified_Anchor_Key__c, AT.Agent_ID__c);
         }
    for(Agent__c X: trigger.new){if(AGMAP.containskey(X.Modified_Anchor_Key__c)) X.Active_Agent_ID__c=AGMAP.get(X.Agent_Id__c);}
      }
I have a working Visualforce page and controller, that searches both Leads & Opportunities for a specific email address, and displays fields if there are any results.

I have been asked by our business department to make a change, adding checkboxes and radio buttons to the page.

I have no idea how I might begin doing this.  Does anyone have any ideas?

Here is the controller:

Public with sharing class AllOppsearchClass{
 Public List<Lead>leadList{get;set;}
 Public List<Opportunity>optyList{get;set;}
   Public String searchStr{get;set;}
   Public AllOppsearchClass(){
   }
     public AllOppsearchClass(ApexPages.StandardController stdController){}
 
    Public void soslDemo_method(){
       leadList = New List<Lead>();
   optyList = New List<Opportunity>();

        
   
   if(searchStr.length() > 1){
   String searchStr1 = '*'+searchStr+'*';
   String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Owner_Name__c,Email,metro__c,Last_Comment__c,statusname__c,Listing_MLS__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,referral_fee__c,last_activity_subject__c),Opportunity(Id,Name,Account_Email__c,Opportunity_EMail__c,metro__c,Last_Comment__c,statusname__c,Owner_Name__c,last_update_date__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,agent__c,referral_fee__c,last_activity_subject__c)';
   List<List <sObject>> searchList = search.query(searchQuery);
   leadList = ((List<Lead>)searchList[0]);
      optyList = ((List<Opportunity>)searchList[1]);
   if(leadList.size() == 0 && optyList.size() == 0){
       apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
       return;
   }
   }
   else{
   apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
   return;
   }
  }
}

And the Visualforce page:

<apex:page standardcontroller="Lead" extensions="AllOppsearchClass">
  <apex:form >
  <apex:inputText value="{!searchStr}"/>
    <apex:commandButton value="Search in Lead, Opportunity" action="{!soslDemo_method}"                reRender="lead,error,oppt" status="actStatusId"/>
    <apex:actionStatus id="actStatusId">
                <apex:facet name="start" >
                    <img src="/img/loading.gif"/>                    
                </apex:facet>
    </apex:actionStatus>
  </apex:form>
 
    <apex:outputPanel title="" id="error">
     <apex:pageMessages ></apex:pageMessages>
     </apex:outputPanel>

     <apex:pageBlock title="Opportunities" id="oppt">
    <apex:pageblockTable value="{!optyList}" var="opty">
     <apex:column headervalue="Name"><apex:outputLink value="/{!opty.ID}" target="_blank">{!opty.name}</apex:outputLink></apex:column>
     <apex:column value="{!opty.Account_Email__c}"/>
     <apex:column value="{!opty.Metro__c}"/>
     <apex:column value="{!opty.Owner_Name__c}"/>
     <apex:column value="{!opty.StatusName__c}"/>
     <apex:column value="{!opty.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!opty.Last_Update_Date__c}"/>     
     <apex:column value="{!opty.Listing_Amount__c}"/>
     <apex:column value="{!opty.Listing_Agent__c}"/>
     <apex:column value="{!opty.Agent__c}"/>
     <apex:column value="{!opty.Referral_Fee__c}"/>
     <apex:column value="{!opty.Last_Comment__c}"/>


       </apex:pageblockTable>
    </apex:pageBlock>
 
    <apex:pageBlock title="Leads" id="lead">
    <apex:pageblockTable value="{!leadList }" var="lead">
     <apex:column headervalue="Name"><apex:outputLink value="/{!lead.ID}" target="_blank">{!lead.name}</apex:outputLink></apex:column>
     <apex:column value="{!lead.email}"/>
     <apex:column value="{!lead.Metro__c}"/>
     <apex:column value="{!lead.Owner_Name__c}"/>
     <apex:column value="{!lead.StatusName__c}"/>
     <apex:column value="{!lead.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!lead.Last_Update_Date__c}"/>
     <apex:column value="{!lead.Listing_Amount__c}"/>
     <apex:column value="{!lead.Listing_MLS__c}"/>
     <apex:column value="{!lead.Listing_Agent__c}"/>
     <apex:column value="{!lead.Referral_Fee__c}"/>
     <apex:column value="{!lead.Last_Comment__c}"/>


 </apex:pageblockTable>
    </apex:pageBlock>
</apex:page>
I have created a Visualforce page with a custom controller that is essentially a search page that I've embedded within the Lead page.  It gives my users the ability to quickly search for duplicates without leaving the page.  The issue is, I'm trying to figure out how to prepopulate the search, so they don't have to copy the email address to the search bar.

Here's the Controller:

Public with sharing class LeadOppsearchclas{
 Public List<Lead>leadList{get;set;}
 Public List<Opportunity>optyList{get;set;}
   Public String searchStr{get;set;}
   Public LeadOppsearchclas(){
   }
 
 public LeadOppsearchclas(ApexPages.StandardController stdController){
 }
 
    Public void soslDemo_method(){
       leadList = New List<Lead>();
   optyList = New List<Opportunity>();
   
   if(searchStr.length() > 1){
   String searchStr1 = '*'+searchStr+'*';
   String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Lead (Id,Name,Email,metro__c,statusname__c,Listing_MLS__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,referral_fee__c,last_activity_subject__c),Opportunity(Id,Name,Account_Email__c,Opportunity_EMail__c,metro__c,statusname__c,Owner_Name__c,date_entered_into_Lead_router__c,listing_amount__c,listing_agent__c,agent__c,referral_fee__c,last_activity_subject__c)';
   List<List <sObject>> searchList = search.query(searchQuery);
   leadList = ((List<Lead>)searchList[0]);
      optyList = ((List<Opportunity>)searchList[1]);
   if(leadList.size() == 0 && optyList.size() == 0){
       apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sorry, no results returned with matching string..'));
       return;
   }
   }
   else{
   apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
   return;
   }
  }
}

And the Visualforce Page:

<apex:page standardcontroller="Lead" extensions="LeadOppsearchclas">
  <apex:form >
  <apex:inputText value="{!searchStr}"/>
    <apex:commandButton value="Search in Lead, Opportunity" action="{!soslDemo_method}"                reRender="lead,error,oppt" status="actStatusId"/>
    <apex:actionStatus id="actStatusId">
                <apex:facet name="start" >
                    <img src="/img/loading.gif"/>                    
                </apex:facet>
    </apex:actionStatus>
  </apex:form>
 
    <apex:outputPanel title="" id="error">
     <apex:pageMessages ></apex:pageMessages>
     </apex:outputPanel>
 
 <apex:pageBlock title="Opportunities" id="oppt">
    <apex:pageblockTable value="{!optyList}" var="opty">
     <apex:column headervalue="Name"><apex:outputLink value="/{!opty.ID}" target="_blank">{!opty.name}</apex:outputLink></apex:column>
     <apex:column value="{!opty.Account_Email__c}"/>
     <apex:column value="{!opty.Metro__c}"/>
     <apex:column value="{!opty.Owner_Name__c}"/>
     <apex:column value="{!opty.StatusName__c}"/>
     <apex:column value="{!opty.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!opty.Listing_Amount__c}"/>
     <apex:column value="{!opty.Listing_Agent__c}"/>
     <apex:column value="{!opty.Agent__c}"/>
     <apex:column value="{!opty.Referral_Fee__c}"/>
     <apex:column value="{!opty.Last_Activity_Subject__c}"/>


       </apex:pageblockTable>
    </apex:pageBlock>
 
    <apex:pageBlock title="Leads" id="lead">
    <apex:pageblockTable value="{!leadList }" var="lead">
     <apex:column headervalue="Name"><apex:outputLink value="/{!lead.ID}" target="_blank">{!lead.name}</apex:outputLink></apex:column>
     <apex:column value="{!lead.email}"/>
     <apex:column value="{!lead.Metro__c}"/>
     <apex:column value="{!lead.StatusName__c}"/>
     <apex:column value="{!lead.Date_Entered_Into_Lead_Router__c}"/>
     <apex:column value="{!lead.Listing_Amount__c}"/>
     <apex:column value="{!lead.Listing_MLS__c}"/>
     <apex:column value="{!lead.Listing_Agent__c}"/>
     <apex:column value="{!lead.Referral_Fee__c}"/>
     <apex:column value="{!lead.Last_Activity_Subject__c}"/>


 </apex:pageblockTable>
    </apex:pageBlock>
</apex:page>
I've spent the last 2 days trying to make some sense of this, and it's killing me.  We have a process wherein leads can either be (1) created with a unique identifier and then are auto-converted (a process which works fine) or (2) are updated after creation (could be hours or days later) with information from our external system, that adds a unique identifier.

I am trying to write a trigger that will recognize this change, and then subsequently convert the lead.

Tests fine, works in sandbox.  In production, I get this error:

Lead DetailError:Apex trigger AgentAdded caused an unexpected exception, contact your administrator: AgentAdded: execution of AfterUpdate caused by: System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00Qo000000J8ITAEA3; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: [] (System Code) : []: Trigger.AgentAdded: line 21, column 1

If anyone can advise on how I should update my trigger, it would be a massive help.  My trigger & test class are below.  Thanks!

Trigger:

Trigger AgentAdded on Lead (after insert, after update) {
LeadStatus convertStatus = [
select MasterLabel
from LeadStatus
where IsConverted = true
limit 1
];
List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
 
for (Lead lead: Trigger.new) {
if (!lead.isConverted && Lead.Agent_ID__c!='0' && Lead.Agent_ID__c !=NULL && Lead.Manually_Routed__c!='TRUE' && Lead.Auto_Assigned__c==FALSE && Lead.Auto_Route__c!='TRUE')
{Database.LeadConvert lc = new Database.LeadConvert();
String oppName = lead.Name;
lc.setLeadId(lead.Id);
lc.setOpportunityName(oppName);
lc.setConvertedStatus(convertStatus.MasterLabel);
leadConverts.add(lc);}
}
 
if (!leadConverts.isEmpty()) {
List<Database.LeadConvertResult> lcr = Database.convertLead(leadConverts);
}
}

TestClass:

@IsTest
private class AgentAddTest {
private static Integer LEAD_COUNT = 0;
private static Lead createLead() {
LEAD_COUNT += 1;
return new Lead(
FirstName = '_unittest_firstname_: ' + LEAD_COUNT,
LastName = '_unittest_lastname_: ' + LEAD_COUNT,
Metro__c='New Jersey'+ LEAD_COUNT,
Status = 'Unread'
);
}
public static void makeFreeTrial(Lead lead) {
lead.Agent_Added__c = TRUE;
lead.agent_id__c='100345678';
}
public static List<Lead> fetchLeads(Set<Id> ids) {
return [
select isConverted
from Lead
where Id in :ids
];
}
public static testMethod void trialConvert() {
Lead testLead = createLead();
makeFreeTrial(testLead);
 
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(results.get(0).isConverted, 'The lead should have been converted since it was a "Free Trail"');
}
 
public static testMethod void nonTrialNoConvert() {
Lead testLead = createLead();
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(!results.get(0).isConverted, 'The lead should not have been converted since it was not a "Free Trial"');
}
public static testMethod void bulkTest() {
List<Lead> shouldBeConverted = new List<Lead>();
List<Lead> shouldNotBeConverted = new List<Lead>();
for (Integer i = 0; i < 50; i++) {
Lead testLeadNonConvert = createLead();
Lead testLeadConvert = createLead();
makeFreeTrial(testLeadConvert);
shouldBeConverted.add(testLeadConvert);
shouldNotBeConverted.add(testLeadNonConvert);
}
List<Lead> toInsert = new List<Lead>();
toInsert.addAll(shouldBeConverted);
toInsert.addAll(shouldNotBeConverted);
Test.startTest();
insert toInsert;
Test.stopTest();
Map<Id, Lead> expectedConversions = new Map<Id, Lead>(shouldBeConverted);
Map<Id, Lead> expectedNonConversions = new Map<Id, Lead>(shouldNotBeConverted);
Set<Id> leadIds = new Set<Id>();
leadIds.addAll(expectedConversions.keySet());
leadIds.addAll(expectedNonConversions.keySet());
for (Lead result: fetchLeads(leadIds)) {
if (expectedConversions.containsKey(result.Id)) {
System.assert(result.isConverted, 'This lead should have been converted ' + result);
expectedConversions.remove(result.Id);
} else if (expectedNonConversions.containsKey(result.Id)) {
System.assert(!result.isConverted, 'This lead should not have been converted ' + result);
expectedNonConversions.remove(result.Id);
} else {
System.assert(false, 'We got a Lead we did not expect to get back ' + result);
}
}
System.assert(expectedConversions.isEmpty(), 'We did not get back all the converted leads we expected');
System.assert(expectedNonConversions.isEmpty(), 'We did not get back all the non converted leads we expected');
}
}
I have a working trigger that updates a lookup field from a zipcode object when the zipcode name = the listing zip code on the lead.  However, I need to add an additional restriction, where the metro__c field on the lead = the metro__c field on the zip code table, and I'm not sure how to do this.  How would I add this restriction?

The working trigger is below:

trigger UpdateListingZip on Lead (before insert, before update) {
    Set<String> ListingZips = new Set<String>();

    for( Lead l : trigger.new ) {
        if( l.listing_zip_code__c != null && l.LAG_Offered__c!=TRUE && l.DTA_Lead__c !=TRUE) {
            ListingZips.add( l.listing_zip_code__c );
                        
 }
    }            

        // Now we have a set of unique zipcodes we want to verify, time to look them up.
    // I plan to build a map of the "match field" -> "full reference object"

    Map<String, zip_codes__c> MatchZips = new Map<String, zip_codes__c>();

    for(zip_codes__c obj : [SELECT  Id,
                                           zipcode__c
                                            FROM    Zip_Codes__c
                                            WHERE     zipcode__c IN :ListingZips] ) {MatchZips.put( obj.zipcode__c, obj );
    }
    // We have all the reference data we need, last loop on the each lead

    for( Lead l : trigger.new ) {

        if( l.listing_zip_code__c != null ) { // there IS a countrylist entry to deal with... so...

            if( MatchZips.containsKey(l.listing_zip_code__c) ) { l.Zip_Code_Lookup__c = MatchZips.get(l.listing_zip_check__c).ID; }}
}
}
I've got a number of lookup fields that I need to populate based on an ID field that will be passed over from our source system.  The custom object is Agent__c.

I've been able to get to 83% coverage (which I know is fine - but we're going to have hundreds of leads processing via this every day - and I want to make sure it won't fail).

Any help/advice would be hugely appreciated.

Here's my trigger:

trigger AgentAssignmentLead on Lead (before insert, before update) {
    Set <String> AgentIDs = new Set <String>();
    for (Lead l : trigger.new) {
        if (l.Agent_ID__c !=NULL) {
            AgentIDs.add (l.Agent_ID__c );
        }
    }
//now we have our list of agent IDs that we want to check against.
//We will build a map of the "match" field

    Map<String, Agent__c> Agents = new map <String, Agent__C>();
    for (Agent__c obj: [SELECT ID,
                        Agent_ID__c
                        from Agent__c
                        Where Agent_ID__C in :AgentIDs]){
                            Agents.put(obj.Agent_ID__c, obj);
                        }
    for (Lead l : trigger.new) {
        if (l.Agent_ID__c !=NULL){
            if (Agents.containsKey(l.Agent_ID__c))
                l.Agent__c=Agents.get(l.Agent_ID__c).ID;
        }
    }
}


And my test class:

@istest
public with sharing class AgentLeadTest {
    public static void UpdateAgent()
    {
        //create the new lead
        Lead Lead = new Lead ();
        Lead.LastName='Adrian';
        Lead.FirstName='Tooms';
        Lead.status='Unread';
        Lead.Metro__c='New Jersey';
        Lead.Agent_ID__c='100683628';
            test.startTest();
        insert Lead;
    }

}