• David Schach
  • NEWBIE
  • 110 Points
  • Member since 2010
  • David Schach
  • salesforce.com


  • Chatter
    Feed
  • 4
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 23
    Replies

Hello all,

 

While I have tonnes of experience with salesforce, my apex previously has been asking my developer.  Thought I would try a simple trigger, or what I thought would be a simple trigger.  Basically, this is what I want it to do:

 

On Cases there is a field called Case_Survey_Sent_Date__c 

On Contacts there is a field called Case_Survey_Sent_Date__c 

 

After the case is saved, I would like to check if the case.Case_Survey_Sent_Date__c is more recent then the contact.Case_Survey_Sent_Date__c and if so, update it.  This is what i have come up with, and lo and behold I am sucking it huge.  Here is what I have so far:

 

trigger updateAccountSurveyDate on Case (after update) {

     Case c;
     for (Contact p = [SELECT id, Case_Survey_Sent_Date__c FROM Contact])
     {
          if (p.Case_Survey_Sent_Date__c < c.Case_Survey_Sent_Date__c){
              p.Case_Survey_Sent_Date__c = c.Case_Survey_Sent_Date__c;
          } else {
               //
          }      
     }
}  

 Now, take a few minutes to compose yourself after the fits of laughter of what I have done...would any of you gurus be able to point me in the error of my ways, or even give me a little to go on?

 

Thanks all,

 

Nik :smileyhappy:

I have written a trigger to standardize Campaign Member Status options. It works great with one exception: it throws a Dupliacte_Value error when I try to Clone a campaign...not sure where to start with debugging.

 

 

trigger autoCampaignMemberStatusTrigger on Campaign (after insert) {
    
    List<Campaign> newCamps = [select Id, RecordType.Name from Campaign where Id IN :trigger.new AND ParentID = Null AND (RecordType.Name = 'Training' OR RecordType.Name = 'Presentation')];
    List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>();
    Set<Id> camps = new Set<Id>();
    List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>();
    List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
    
    for(Campaign camp : newCamps){
       
            camps.add(camp.Id);
    }   
    
    for(CampaignMemberStatus cm : [select Id, Label, CampaignId from CampaignMemberStatus where CampaignId IN :camps]) {
            if(cm.Label == 'Sent' || cm.Label == 'Responded') {             
                 cms2Delete.add(cm);                 
            }
            
            CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false,
             Label = 'Invited', SortOrder = 3, isDefault = true);
             cms2Insert.add(cms1);          
            
            CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Accepted', SortOrder = 4);
             cms2Insert.add(cms2);
             
            CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Attended', SortOrder = 5);
             cms2Insert.add(cms3); 
             
             CampaignMemberStatus cms4 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Declined', SortOrder = 6);
             cms2Insert.add(cms4);
    }
    
    insert cms2Insert;
    delete cms2Delete;
}

 

 

There seems to be nothing in the Apex guides on how to test a set controller.  This method runs when a button is clicked on a custom object list view and processes the records selected from the list view.

 

How do I test it?  I can't figure out how to get any records "selected" in the StandardSetController.

 

 

public with sharing class replacerRunAllSelectedRulesController{

    ApexPages.StandardSetController setCon;
    private PageReference savePage;

    public replacerRunAllSelectedRulesController(ApexPages.StandardController controller) {
        //Not sure why this is needed...
    }//replacerRunAllSelectedRulesController

    public replacerRunAllSelectedRulesController(ApexPages.StandardSetController controller) {
        setCon=controller;
        List<Replacer__c> selectedRules=new List<Replacer__c>();
    }//replacerRunAllSelectedRulesController
    

    public PageReference runSelectedRules(){
        List<Replacer__c> selectedRules=new List<Replacer__c>();
        for(sObject s: setCon.getSelected()){
            Replacer__c r=(Replacer__c)s;
            selectedRules.add(r);
        }//for 1
        String objectName='';
        Boolean sendEmail=TRUE;
        
        if(selectedRules.size()==0){
        	ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 
        	'You must select at least one rule.  Please go back and select a rule by checking the checkbox and try again.'));        
        }else{
	        
	        Integer numJobsCantBeRunNow=replacerExecute.replacerQueueBatchJobs(objectName, selectedRules, sendEmail);
	        if(numJobsCantBeRunNow==0){
	            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.CONFIRM,'Replacement has begun.  This can take ~10-30 minutes for each 10,000 records.  You will receive 1 email confirmation for each different object as all rules for one object are run together in one job.');
	            ApexPages.addMessage(myMsg);
	        }else{
	            //else throw an error that they need to select fewer rules to run right now
	            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'The selected rules cannot be run now as they would exceed your companies batch job limit of 5.  One job is created for each different object.  Please unselect ' + numJobsCantBeRunNow + ' object\'s rules and try again.  To view the batch queue, click Setup-->Monitoring-->Apex Jobs'));
	        }//if 2
        }//if 1
        
        return ApexPages.CurrentPage();
    }//runSelectedRules
    
}//replacerRunAllSelectedRulesController

 

Here's where I'm at - I have the controller assigned, but can't figure out how to select the records in the set controller:

 

 

public static testMethod void verifyListViewRunSelectedRulesButton() {
	Boolean deleteReplacers=TRUE;
        Boolean deleteQueuedJobs=FALSE;
        Boolean deleteFieldList=FALSE;
        Boolean deleteTestData=TRUE;
        Boolean deleteJobHistory=FALSE;
        Boolean abortBatchJobs=FALSE;
        //There should be zero replacers after this method runs
        deleteTestData(deleteReplacers, deleteQueuedJobs, deleteFieldList, deleteTestData, deleteJobHistory, abortBatchJobs);

        //Make 1 active rule so that a preview can be shown
        Boolean rActive=TRUE;
        String rObjectName='test__c';
        String rFieldName='picklist__c';
        String rFind='a';
        String rValue='b';
        List<replacer__c> rules=new List<replacer__c>();
        rules.add(createRule(rActive, rObjectName, rFieldName, rFind, rValue));
        rFieldName='text__c';
        rules.add(createRule(rActive, rObjectName, rFieldName, rFind, rValue));
        insert rules;

        Long numRecords=2;
        Date dat=date.today();
        DateTime datTim=dateTime.now();
        Decimal dec=0.123;
        String em='a@a.com';
        String ph='415-555-1234';
        String pick='a';            
        String text='a';
        String ur='http://www.google.com';

        //Insert some test data so we can play with the controller
        List<test__c> ts=createTestRecords(numRecords, dat, datTim, dec, em, ph, pick, text, ur); 
        pick='c';
        List<test__c> ts2=createTestRecords(1, dat, datTim, dec, em, ph, pick, text, ur);
        
        ApexPages.StandardSetController sc = new ApexPages.StandardSetController(rules);
        replacerRunAllSelectedRulesController scExt = new replacerRunAllSelectedRulesController(sc);
	//How do I select both "rules"?	
        test.StartTest();
            scExt.runSelectedRules();
        test.stopTest();

	List<test__c> results=[SELECT Id, picklist__c FROM test__c WHERE Id IN: ts];
        for(test__c t: results){
            system.assertEquals(rValue, t.picklist__c);
        }//for

        List<test__c> results2=[SELECT Id, picklist__c FROM test__c WHERE Id IN: ts2];
        for(test__c t: results2){
            system.assertEquals(pick, t.picklist__c);
        }//for
        
    }//verifyListViewRunSelectedRulesButton

 

 

 

 

 

Hi All,

      Does anybody know if there is any app or any tool for validating the address in Sfdc...

 

 

TIA!

Hi All!

 

Our team is currently working on docuSign for Salesforce integration. Does anyone know if bulk voiding of envelopes are possible? Right now we are limiting voiding of envelopes to 9 due to some limits in docuSign. Is there a way where we can void multiple envelopes all at once? Please help because this is an urgent matter. Thanks in advance.

During a batch apex job I have noticed the number of Total Batches is changing, lowering. It starts high and then as the job progresses the number starts to lower. It would also appear that the batch apex job is missing some of the records that should have been originally queried and are never being processed by the batch apex class.

 

Here are some images showing the drop as the batch job progresses:

1670 Total Batches

 

1623 Total Batches

 

1527 Total Batches after complete

 

The difference is 143 batches or 29,000 records which is exactly how many records are not being processed.

 

This is bizarre. Any ideas?

 

Thanks,

Jason

Hello all,

 

While I have tonnes of experience with salesforce, my apex previously has been asking my developer.  Thought I would try a simple trigger, or what I thought would be a simple trigger.  Basically, this is what I want it to do:

 

On Cases there is a field called Case_Survey_Sent_Date__c 

On Contacts there is a field called Case_Survey_Sent_Date__c 

 

After the case is saved, I would like to check if the case.Case_Survey_Sent_Date__c is more recent then the contact.Case_Survey_Sent_Date__c and if so, update it.  This is what i have come up with, and lo and behold I am sucking it huge.  Here is what I have so far:

 

trigger updateAccountSurveyDate on Case (after update) {

     Case c;
     for (Contact p = [SELECT id, Case_Survey_Sent_Date__c FROM Contact])
     {
          if (p.Case_Survey_Sent_Date__c < c.Case_Survey_Sent_Date__c){
              p.Case_Survey_Sent_Date__c = c.Case_Survey_Sent_Date__c;
          } else {
               //
          }      
     }
}  

 Now, take a few minutes to compose yourself after the fits of laughter of what I have done...would any of you gurus be able to point me in the error of my ways, or even give me a little to go on?

 

Thanks all,

 

Nik :smileyhappy:

Here is the scenario:

Upon the insert of an OpportunityLineItem the PricebookEntry field will not be defined. A before insert trigger will need to populate this value. On the insert there is a custom field that lists the product name, product names are unique.

Sounds simple right? but I can't find an efficient way to query the pricebook entries without returning more records than are required.

The Setup:

Opportunities:
Opp ABC (Id = 7777, Pricebook2Id = 1)
Opp DEF (Id = 8888, Pricebook2Id = 2)

Products:
Widget1 (ID = 1234)
Widget2 (ID = 5678)

PricebookEntries:
PBE1 (Pricebook2Id = 1, Name = Widget1, Product2Id = 1234)
PBE2 (Pricebook2Id = 1, Name = Widget2, Product2Id = 5678)
PBE3 (Pricebook2Id = 2, Name = Widget1, Product2Id = 1234)
PBE4 (Pricebook2Id = 2, Name = Widget2, Product2Id = 5678)

Line Items being inserted:
OpportunityLineItem(OpportunityId = 7777, Product_Name__c = Widget1)
OpportunityLineItem(OpportunityId = 8888, Product_Name__c = Widget2)

On the OpportunityLineItems being inserted I need a trigger to set the PricebookEntryId field. Below is this trigger:

 

trigger RenewalLineInsert on OpportunityLineItem (before insert) {
	Set<String> productNames = new Set<String>();
	Set<Id> oppIds = new Set<Id>();
	Map<Id,Id> oppPricebookMap = new Map<Id,Id>();
	Map<Id,Map<String,Id>> pricebookProductMap = new Map<Id,Map<String,Id>>();
	
	//Add product names and opp ids to sets for future queries
	for(OpportunityLineItem oli : trigger.new){
		productNames.add(oli.Product_Name__c);	
		oppIds.add(oli.OpportunityId);
	}
	
	//Query the related opportunities and get the pricebook2Id, put in map OppId -> Pricebook2Id
	for(Opportunity opp : [select Id, Pricebook2Id from Opportunity where Id IN :oppIds]){
		oppPricebookMap.put(opp.Id,opp.Pricebook2Id);
	}
	
	//Query the pricebook entries, add to a map Pricebook2Id -> (Product Name -> PricebookEntryId)
	for(PricebookEntry pbe : [select Id, Name, Pricebook2Id from PricebookEntry where Name IN :productNames AND Pricebook2Id IN :oppPricebookMap.values()]){
		system.debug(pbe);
		
		//Check to see if the map of pricebooks to producs contains an innter map, if not create
		if(pricebookProductMap.get(pbe.Pricebook2Id) == null){
			pricebookProductMap.put(pbe.Pricebook2Id,new Map<String,Id>());
		}
		
		//Add Product to map
		pricebookProductMap.get(pbe.Pricebook2Id).put(pbe.Name,pbe.Id);
	}
	
	//Loop through the inserted Line Items and set the PricebookEntryId field
	for(OpportunityLineItem oli : trigger.new){
		Id pricebookId = oppPricebookMap.get(oli.OpportunityId);
		oli.PricebookEntryId = pricebookProductMap.get(pricebookId).get(oli.Product_Name__c);
	}
}

There is a problem with this trigger and it is the query on the pricebook entries table. We are only inserting two line items so ideally we when querying the pricebook entries we should only get two results. But this query with the two IN filters will actually return all four pricebook entries even though we only need two.

This trigger works but it could be better and I am obsessed with my code being efficient. If you know of a way to make this trigger better and only query the actual number of PricebookEntry records needed I will buy you a bear at Dreamforce.

Thanks,
Jason

  • August 11, 2011
  • Like
  • 0

I have written a trigger to standardize Campaign Member Status options. It works great with one exception: it throws a Dupliacte_Value error when I try to Clone a campaign...not sure where to start with debugging.

 

 

trigger autoCampaignMemberStatusTrigger on Campaign (after insert) {
    
    List<Campaign> newCamps = [select Id, RecordType.Name from Campaign where Id IN :trigger.new AND ParentID = Null AND (RecordType.Name = 'Training' OR RecordType.Name = 'Presentation')];
    List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>();
    Set<Id> camps = new Set<Id>();
    List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>();
    List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
    
    for(Campaign camp : newCamps){
       
            camps.add(camp.Id);
    }   
    
    for(CampaignMemberStatus cm : [select Id, Label, CampaignId from CampaignMemberStatus where CampaignId IN :camps]) {
            if(cm.Label == 'Sent' || cm.Label == 'Responded') {             
                 cms2Delete.add(cm);                 
            }
            
            CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false,
             Label = 'Invited', SortOrder = 3, isDefault = true);
             cms2Insert.add(cms1);          
            
            CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Accepted', SortOrder = 4);
             cms2Insert.add(cms2);
             
            CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Attended', SortOrder = 5);
             cms2Insert.add(cms3); 
             
             CampaignMemberStatus cms4 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
             Label = 'Declined', SortOrder = 6);
             cms2Insert.add(cms4);
    }
    
    insert cms2Insert;
    delete cms2Delete;
}

 

 

There are several posts on here regarding the infamouse non-selective query error but it has never really been clearly addressed from salesforce.com. Here is the error:

System.QueryException: Non-selective query against large object type (more than 100000 rows). Consider an indexed filter or contact salesforce.com about custom indexing.
Even if a field is indexed a filter might still not be selective when:
1. The filter value includes null (for instance binding with a list that contains null)
2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times)


Here is a query causing this error:

for(Opportunity opp : [select Id from Opportunity where EvalCondSBSO__c = '123456']){
    system.debug(opp);
}

 

This error doesn't make sense because it does not seem relevant. For starters, the query is selective. Also:
1) The filter value does not include nulls
2) The number of match rows returned would be very minimal.

The only thing that even starts to make sense is the Opportunity table has 250,000 rows. So really, is there simply a limitation that triggers cannot query tables with more than 100K rows? If so, this should be documented somewhere.

Thanks,
Jason

 

There seems to be nothing in the Apex guides on how to test a set controller.  This method runs when a button is clicked on a custom object list view and processes the records selected from the list view.

 

How do I test it?  I can't figure out how to get any records "selected" in the StandardSetController.

 

 

public with sharing class replacerRunAllSelectedRulesController{

    ApexPages.StandardSetController setCon;
    private PageReference savePage;

    public replacerRunAllSelectedRulesController(ApexPages.StandardController controller) {
        //Not sure why this is needed...
    }//replacerRunAllSelectedRulesController

    public replacerRunAllSelectedRulesController(ApexPages.StandardSetController controller) {
        setCon=controller;
        List<Replacer__c> selectedRules=new List<Replacer__c>();
    }//replacerRunAllSelectedRulesController
    

    public PageReference runSelectedRules(){
        List<Replacer__c> selectedRules=new List<Replacer__c>();
        for(sObject s: setCon.getSelected()){
            Replacer__c r=(Replacer__c)s;
            selectedRules.add(r);
        }//for 1
        String objectName='';
        Boolean sendEmail=TRUE;
        
        if(selectedRules.size()==0){
        	ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 
        	'You must select at least one rule.  Please go back and select a rule by checking the checkbox and try again.'));        
        }else{
	        
	        Integer numJobsCantBeRunNow=replacerExecute.replacerQueueBatchJobs(objectName, selectedRules, sendEmail);
	        if(numJobsCantBeRunNow==0){
	            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.CONFIRM,'Replacement has begun.  This can take ~10-30 minutes for each 10,000 records.  You will receive 1 email confirmation for each different object as all rules for one object are run together in one job.');
	            ApexPages.addMessage(myMsg);
	        }else{
	            //else throw an error that they need to select fewer rules to run right now
	            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'The selected rules cannot be run now as they would exceed your companies batch job limit of 5.  One job is created for each different object.  Please unselect ' + numJobsCantBeRunNow + ' object\'s rules and try again.  To view the batch queue, click Setup-->Monitoring-->Apex Jobs'));
	        }//if 2
        }//if 1
        
        return ApexPages.CurrentPage();
    }//runSelectedRules
    
}//replacerRunAllSelectedRulesController

 

Here's where I'm at - I have the controller assigned, but can't figure out how to select the records in the set controller:

 

 

public static testMethod void verifyListViewRunSelectedRulesButton() {
	Boolean deleteReplacers=TRUE;
        Boolean deleteQueuedJobs=FALSE;
        Boolean deleteFieldList=FALSE;
        Boolean deleteTestData=TRUE;
        Boolean deleteJobHistory=FALSE;
        Boolean abortBatchJobs=FALSE;
        //There should be zero replacers after this method runs
        deleteTestData(deleteReplacers, deleteQueuedJobs, deleteFieldList, deleteTestData, deleteJobHistory, abortBatchJobs);

        //Make 1 active rule so that a preview can be shown
        Boolean rActive=TRUE;
        String rObjectName='test__c';
        String rFieldName='picklist__c';
        String rFind='a';
        String rValue='b';
        List<replacer__c> rules=new List<replacer__c>();
        rules.add(createRule(rActive, rObjectName, rFieldName, rFind, rValue));
        rFieldName='text__c';
        rules.add(createRule(rActive, rObjectName, rFieldName, rFind, rValue));
        insert rules;

        Long numRecords=2;
        Date dat=date.today();
        DateTime datTim=dateTime.now();
        Decimal dec=0.123;
        String em='a@a.com';
        String ph='415-555-1234';
        String pick='a';            
        String text='a';
        String ur='http://www.google.com';

        //Insert some test data so we can play with the controller
        List<test__c> ts=createTestRecords(numRecords, dat, datTim, dec, em, ph, pick, text, ur); 
        pick='c';
        List<test__c> ts2=createTestRecords(1, dat, datTim, dec, em, ph, pick, text, ur);
        
        ApexPages.StandardSetController sc = new ApexPages.StandardSetController(rules);
        replacerRunAllSelectedRulesController scExt = new replacerRunAllSelectedRulesController(sc);
	//How do I select both "rules"?	
        test.StartTest();
            scExt.runSelectedRules();
        test.stopTest();

	List<test__c> results=[SELECT Id, picklist__c FROM test__c WHERE Id IN: ts];
        for(test__c t: results){
            system.assertEquals(rValue, t.picklist__c);
        }//for

        List<test__c> results2=[SELECT Id, picklist__c FROM test__c WHERE Id IN: ts2];
        for(test__c t: results2){
            system.assertEquals(pick, t.picklist__c);
        }//for
        
    }//verifyListViewRunSelectedRulesButton

 

 

 

 

 

I have written a test that runs 100% successfully on the full development environment. When I attempt to validate deployment to the production server, it fails with the 'External Entry Point' Error on the last assert in my leadTransferTest() method. I have compared the objects on both the production and dev environments and cannot find any difference. Any help/suggestions would be greatly appreciated!!

 

private class LeadUtilsControllerTest {

    static testMethod void leadTransferTest() {
        //Create a Region
        Region__c region = new Region__c();
        region.Name = 'San Francisco';
        insert region;
        
        //Create a Zone
        Zone__c zone = new Zone__c();
        zone.Region__c = region.Id;
        zone.Name = 'Zone 1';
        
        //Create a Zipcode
        Zip_Code__c zipcode = new Zip_Code__c();
        zipcode.Zone__c = zone.Id;
        zipcode.Name = '94002';
                
        //Create a Lead
        Lead lead = new Lead();
        lead.Company = 'Company Name';
        lead.FirstName = 'FName';
        lead.LastName = 'LName';
        lead.Region__c = 'San Francisc';
        lead.PostalCode = '94002';
        insert lead;
        
        //Start test
        test.startTest();
        
        //Set Current Page
        PageReference currPage = new PageReference('/apex/LeadUtils');
        System.test.setCurrentPage(currPage);
        
        //Initialize Controller
        LeadUtilsController controller = new LeadUtilsController();
        
           //Set old and new regions
           controller.oldRegion = 'San Francisc';
           controller.newRegion = 'San Francisco';
        
           //Check to see if getItems has more than 0 items
           System.assert(controller.getItems().size() > 0);
           
           //Run transfer method
           controller.updateRegion();
           
           //Requery the leads
        Lead leadTest = [SELECT Id, PostalCode, Region__c, ZipCode__c FROM Lead WHERE Id = :lead.Id];
        
           system.debug('--TEST lead.Region__c before method:' + lead.Region__c);
           system.debug('--TEST leadTest.Region__c after method:' + leadTest.Region__c);
           system.debug('--TEST controller.newRegion:' + controller.newRegion);
        
           //Assert that the lead's region was changed
        System.assert(leadTest.Region__c == controller.newRegion);
        
        //Stop test
        test.stopTest();
    }
    
    static testMethod void leadTransferFailedTest() {
        //Create a Region
        Region__c region = new Region__c();
        region.Name = 'San Francisco';
        insert region;
        
        //Create a Zone
        Zone__c zone = new Zone__c();
        zone.Region__c = region.Id;
        zone.Name = 'Zone 1';
        
        //Create a Zipcode
        Zip_Code__c zipcode = new Zip_Code__c();
        zipcode.Zone__c = zone.Id;
        zipcode.Name = '94002';
                
        //Create a Lead
        Lead lead = new Lead();
        lead.Company = 'Company Name';
        lead.FirstName = 'FName';
        lead.LastName = 'LName';
        lead.Region__c = 'San Francisc';
        lead.ZipCode__c = zipcode.Id;
        lead.PostalCode = '85220';
        insert lead;
           
        //Start test
        test.startTest();
        
        //Set Current Page
        PageReference currPage = new PageReference('/apex/LeadUtils');
        System.test.setCurrentPage(currPage);
        
        //Initialize Controller
        LeadUtilsController controller = new LeadUtilsController();
        
           //Set old and new regions
           controller.oldRegion = 'San Francisc';
           controller.newRegion = 'San Francisco';
        
           //Run transfer method
           controller.updateRegion();
           
        //Stop test
        test.stopTest();
           
           //Assert that there was an error message
        System.assert(ApexPages.hasMessages(ApexPages.Severity.ERROR));
    }
    
    static testMethod void leadRemapTest() {     
        //Create a Region
        Region__c region = new Region__c();
        region.Name = 'San Francisco';
        insert region;
        
        //Create a Zone
        Zone__c zone = new Zone__c();
        zone.Region__c = region.Id;
        zone.Name = 'Zone 1';
        
        //Create a Zipcode
        Zip_Code__c zipcode = new Zip_Code__c();
        zipcode.Zone__c = zone.Id;
        zipcode.Name = '94002';
                
        //Create a Lead
        Lead lead = new Lead();
        lead.Company = 'Company Name';
        lead.FirstName = 'FName';
        lead.LastName = 'LName';
        lead.Region__c = 'San Francisco';
        lead.PostalCode = '94002';
        insert lead;
        
        //Start test
        test.startTest();
        
        //Set Current Page
        PageReference currPage = new PageReference('/apex/LeadUtils');
        System.test.setCurrentPage(currPage);
        
        //Initialize Controller
        LeadUtilsController controller = new LeadUtilsController();
        
           //Set old and new regions
           controller.newRegionMap = 'San Francisco';
        
           //Run remap method
           controller.remapRegion();
        
           //Assert that there was no error message
        System.assert(ApexPages.hasMessages(ApexPages.Severity.INFO));
        
        //Stop test
        test.stopTest();
    }
    
    static testMethod void leadRemapNoLeadsTest() {
        //Start test
        test.startTest();     
        
        //Set Current Page
        PageReference currPage = new PageReference('/apex/LeadUtils');
        System.test.setCurrentPage(currPage);
        
        //Initialize Controller
        LeadUtilsController controller = new LeadUtilsController();
        
           //Set old and new regions
           controller.newRegionMap = 'San Francisco';
        
           //Run remap method
           controller.remapRegion();
        
           //Assert that there was no error message
        System.assert(ApexPages.hasMessages(ApexPages.Severity.ERROR));
        
        //Stop test
        test.stopTest();
    }
}

Hi All,

      Does anybody know if there is any app or any tool for validating the address in Sfdc...

 

 

TIA!

With some help, I've developed the trigger below that is fully funtional and operates as designed. In a nut shell, it performs two primary functions.

 

  1. Sends an email to the contact - assuming that the criteria is satisfied
  2. Updates the contact to indicate that an email has been sent. (This could be satisifed w/ activity reporting but deferred to a tracking within the contact since direct contact reporting is simplier than the often inferred reporting that occurs with activities)

With the update of epc_invite_sent__c at the end of the statement, this trigger fires twice (assuming the criteria is met initially) once to send the email and again to make the update to epc_invite_sent__c. The trigger then exits if the IF statement is not satisfied.

 

Being a neophyte developer, I am wondering if this is the best approach for the trigger to fire twice. Though it works, I am thinking that there might be a better approach that I am not aware of that might be more efficient and or less "expensive" from a query stand point.

 

Welcome the thoughts and best practice pointers. Thanks.

 

 

trigger EPC_Invite_EmailMessage on Contact (after insert, after update) {

  for (Contact c : Trigger.new){
    Account a = [Select id, ESR_or_GDS__c, Parent_Chain__c From Account Where Id = :c.AccountId];
    if(c.HasOptedOutofEmail == FALSE &&
       c.RecordTypeId == '012500000009AB1' && //Standard Contact
       c.EPC_Invite_Sent__c == FALSE &&
       c.Opt_out_acme_Partner_Central__c == FALSE &&
       c.No_Longer_There_Do_not_email__c == FALSE &&
       c.EPC_Invite_Sent__c == FALSE &&
       a.ESR_or_GDS__c == 'ESR' &&
       a.Parent_Chain__c != Null &&
      (a.Parent_Chain__c != 'a0L50000000LQWw' || 
       a.Parent_Chain__c != 'a0L70000002eIb3' || 
       a.Parent_Chain__c != 'a0L50000000LQYL')) {

       String template = ''; // initialize variable to hold template name filled in below
       if(c.Language__c == 'Arabic'||   
          c.Language__c == 'Armenian'|| 
          c.Language__c == 'Bengali'||
          c.Language__c == 'English'||
          c.Language__c == 'Hindi (urdu)'||
          c.Language__c == 'Lithuanian'||
          c.Language__c == 'Malay (Malaysia)'||
          c.Language__c == 'Romanian'||
          c.Language__c == 'Serbian'||
          c.Language__c == 'Slovak'||
          c.Language__c == 'Ukrainian') {
         //set to english template
         template = 'EPC Invite - English';
       }
       else {
         //set to english template 
         template = 'EPC Invite - ' + c.Language__c;
       }
       
       Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
       message.setTemplateId([select id from EmailTemplate where Name = :template].id);
       
       message.setTargetObjectId(c.id);
       
       // String to hold the email addresses to which the email is being sent. 
       message.setToAddresses (new String[] {c.Email});

       // Send message under cover of org wide email address xreply@acme.com instead of user that executed trigger
       message.setOrgWideEmailAddressId('0D2T00000004CL9');

       // Send the email that has been created.  
       Messaging.sendEmail(new Messaging.Email[] {message});
       
       Contact contact = [Select ID
                           From Contact
                          Where Id = :c.Id];
                          
       contact.EPC_Invite_Sent__c = true;       
       update contact;
         
    }
  }
}

 

 

 

 

I wonder if this is a bug? I am having the same trouble discussed here. The following formula, as an "onclick javascript" custom button, correctly opens and prepopulates a new purchase_items__c, but when I press "save", I am taken to the new item rather than to the containing purchase order.

 

I'm sure that the retURL is correct, because the cancel button does take me back to the purchase order.

 

 

Here's the formula (I added spaces here for readability; it seems they must be removed for the formula to work):

navigateToUrl('{!URLFOR($Action.SFDC_Purchase_Items__c.New,null,

[retURL=URLFOR($Action.SFDC_Purchase_Order__c.View,SFDC_Purchase_Order__c.Id),

CF00N200000014eaJ=SFDC_Purchase_Order__c.Name,

CF00N200000014eaJ_lkid=SFDC_Purchase_Order__c.Id]

)}')

 

 

 

Message Edited by Shikibu on 08-20-2009 12:39 PM
I have a data table that returns a double in one of the columns that represents currency but I am having a difficult time getting this to display correclty in a dataTable.

Essentially I want to go from this:

to this:


Thanks,
Jason