• crop1645
  • PRO
  • 2149 Points
  • Member since 2008

  • Chatter
    Feed
  • 73
    Best Answers
  • 4
    Likes Received
  • 0
    Likes Given
  • 16
    Questions
  • 520
    Replies

Hi,

 

If the exception happens in UI controller or trigger, the exception can be caught, and then be presented to UI through VF apex:message. I wonder what's Best practice for notifying exception in future method or batch job where there's no UI interface directly to user. I can only think of 2 options, 1) catch the exeption, and put either the raw error message or user-friendly error message into debug log, 2) catch the exception, and throw an new exception with a user-friendly error message; and this exception will be logged into apex job execution result by SFDC.

 

Any other thoughts?

Is it implementation of stack concept in apex class or something else??

  • October 08, 2013
  • Like
  • 0

Can anyone find the problem with this code please:

trigger SalesHistoryRecordTypeTrigger on Account (after insert, after update){
 //One query, fill two maps. 
Map<String,Id> accountRecordTypes = new Map<String,Id>();
 Map<String,Id> ytdRTMap = new Map<String,Id>(); 
for(RecordType rt: [Select Name, Id, sObjectType From RecordType Where sObjectType in ('Account','Sales_History_YTD__c')and isActive=true]) { 
    if(String.valueof(rt.sObjectType).equalsIgnoreCase('Account')){
       accountRecordTypes.put(rt.Name,rt.Id); } 
  else{ ytdRTMap.put(rt.name,rt.Id); } 
} 
for(Account a : Trigger.new){ 
if(a.RecordTypeId == accountRecordTypes.get('Regional_View_Lit_ppl')){
    Sales_History_YTD__c.RecordTypeId = ytdRTMap.get('Regional_View_Record'); } 
else 
if(a.RecordTypeId == accountRecordTypes.get('Dollar View')){ 
    Sales_History_YTD__c.RecordTypeId = ytdRTMap.get('Page Layout Dollar view'); } 
else if(a.RecordTypeId == accountRecordTypes.get('Dual Currency View')){
    Sales_History_YTD__c.RecordTypeId = ytdRTMap.get('Page Layout Dual View'); }
 }
 } 

 

I am trying to change the record type of a child object (Sales_History_YTD__c) whenever a record type of its parent object changes (Account).

 

Your help is much appreciated.

I am trying to get better coverage of a particular controller extension and am having a few issues with one particular line.  I have a custom object where I store a task Id and a user Id and a few other fields.  This class is meant to query, insert, or delete records in that object.

 

In the getInformedUsers method below, all the lines test fine with the exception of the Return property.  I keep getting a Attempt to dereference a null object error.  The only other place where I can't seem to get coverage is in the removeInformed method for the redirect lines.  

 

I am currently at 61% pass if I do not test the getInformedUsers method but would love figure out how to cover that as well.  Code below:

 

public with sharing class informedUserList {
	
	private ApexPages.StandardController controller;
	
	
	public informedUserList(ApexPages.StandardController stdController) {     
      controller = stdController;
   }	   
	public List<Task_Informed_Users__c> getInformedUsers() {
		
		String tskID = ApexPages.currentPage().getParameters().get('Id');
		String longTaskId = String.valueOf(tskId);
		String shortTaskId = longTaskId.left(15);	
		     
        return [SELECT id, Informed_User__r.Name, Chatter_Notification__c, Send_Email__c FROM Task_Informed_Users__c WHERE Task_Id__c =: shortTaskId];
    }   
    
	public PageReference addInformed() {		
		string tskId = ApexPages.currentPage().getParameters().get('Id');		
		
		PageReference tskInformed = new pagereference('/apex/informedUsers?tId='+tskId);
		tskInformed.setRedirect(true);
  		return tskInformed;  			

	}

	public PageReference removeInformed() {		
		string tskId = ApexPages.currentPage().getParameters().get('Id');
		Id iuRecId = System.currentPageReference().getParameters().get('iuRec');
		
		delete [select id from Task_Informed_Users__c where ID=: iuRecId ]; 

   		return null;
		
		PageReference tskInformed = new pagereference('/apex/taskDetail?Id='+tskId);
		tskInformed.setRedirect(true);
  		return tskInformed;  			

	}
	
    
    public static Task testTsk;
    public static Task_Informed_Users__c testInformedUser;
    public static ID testTaskId;
    public static User testUserId;
        
    static testMethod void informedUserListTest() {    	
    	Test.startTest();
    	
    	testUserId = [SELECT ID FROM User WHERE LastName=: 'User2'];
        testTsk = new Task(Subject='testTask', ownerId=testUserId.Id); 
        insert testTsk;
        testTaskId = testTsk.Id;
            
        testInformedUser = new Task_Informed_Users__c(Informed_user__c=testUserId.Id, Task_ID__c=testTaskId, Chatter_Notification__c=FALSE, Send_Email__c=FALSE);
        insert testInformedUser;
        
        Test.setCurrentPage(Page.taskDetail);
		ApexPages.currentPage().getParameters().put('tId',testTaskId);         
              
        ApexPages.StandardController con = new ApexPages.StandardController(testInformedUser);
        informedUserList tInformedUserList = new informedUserList(con); 
        
        tInformedUserList.addInformed();  //Tests Fine
      
        tInformedUserList.removeInformed(); //Tests all but the redirect code    
        
        tInformedUserList.getInformedUsers();  //Get Attempt to DeReference a Null Object error
           
        
        Test.stopTest();        
    }
      
}

 

  • September 09, 2013
  • Like
  • 0

Hello Everyone,

 

I have got the following trigger on opportunity which should check if the opportunity stage = closedwon, product2.family = membership (Picklist). If this critera is matched with an opportunity it gets cloned and stage gets assigned to 'Completed' and closedate = date+365 days:

 

 

Code:

 

trigger OpportunityTester on Opportunity (after update) {
List<Opportunity> oppwithproduct = [select id,(select id From OpportunityLineItems where Pricebookentry.product2.Family = 'membership') 
from Opportunity where StageName = 'Closed Won'];
Oppwithproduct = Trigger.new; 
OpportunityFetcher.Opportunityreplicate(Oppwithproduct);
}

public class OpportunityFetcher{
    public static void Opportunityreplicate(List<Opportunity> Oppwithproduct){
        Set<id> OppIDs = new set<id>(); // Creating a set for storing Opportunity ids
        List<Opportunity> oppsToClone = new List<Opportunity>{};
        for(Opportunity opp:Oppwithproduct){
            //oppsToClone.add(newopp);
            Opportunity newOpp = new Opportunity();
            newOpp = opp.clone(false, true);
            newopp.Name = opp.Name;
            newopp.StageName = 'Completed';
            newopp.CloseDate = (opp.CloseDate+365);
            oppsToClone.add(newopp);
        }
        insert oppsToClone;
    }
}

 I am getting following error:

 

Validation Errors While Saving Record(s)

There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger OpportunityTester caused an unexpected exception, contact your administrator: OpportunityTester: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, OpportunityTester: maximum trigger depth exceeded Opportunity trigger event AfterUpdate for [006c0000007wqqI] Opportunity trigger event AfterUpdate for [006c0000007wqqJ] Opportunity trigger event AfterUpdate for [006c0000007wqqK] Opportunity trigger event AfterUpdate for [006c0000007wqqL] Opportunity trigger event AfterUpdate for [006c0000007wqqM] Opportunity trigger event AfterUpdate for [006c0000007wqqN] Opportunity trigger event AfterUpdate for [006c0000007wqqO] Opportunity trigger event AfterUpdate for [006c0000007wqqP] Opportunity trigger event AfterUpdate for [006c0000007wqqQ] Opportunity trigger event AfterUpdate for [006c0000007wqqR] Opportunity trigger event AfterUpdate for [006c0000007wqqS] Opportunity trigger event AfterUpdate for [006c0000007wqqT] Opportunity trigger event AfterUpdate for [006c0000007wqqU] Opportunity trigger event AfterUpdate for [006c0000007wqqV] Opportunity trigger event AfterUpdate for [006c0000007wqqW] Opportunity trigger event AfterUpdate for [006c0000007wqqX]: []: Class.OpportunityFetcher.Opportunityreplicate: line 14, column 1". 

 

Any help guys??

 

  • September 06, 2013
  • Like
  • 0

There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger CaseUpdates caused an unexpected exception, contact your administrator: CaseUpdates: execution of BeforeUpdate caused by: System.ListException: DML statment found null SObject at position 0: Class.PropertyUpdatebyCode.PropertyUpdatebyCode: line 23, column 1". 

 

 

Getting this error anytime the for loop should be populating my properties array. 

 

 

Apex Class

 

public class PropertyUpdatebyCode{

      Public List<Case> lstNewCases = new List<Case>();
      Public List<Case> lstOldCases = new List<Case>();
    
        public void PropertyUpdatebyCode() {

 

        //variables
        Map<Id,Case>  mapVerifyOldCases=new Map<Id,Case>();
        List<Property_Account__c> properties = new list<Property_Account__c>();
        

 

        //populates map with old values for comparison
        For(Case CaseOld : lstOldCases){ mapVerifyOldCases.put(CaseOld.id,CaseOld);}
        

 

        //populates array for DML update expression
        For(Case CaseNew: lstNewCases){ 
            IF(CaseNew.Property__c!=Null && 

                CaseNew.XLS01__c==TRUE &&

                (CaseNew.IsClosed != mapVerifyOldCases.get(CaseNew.Id).IsClosed || 

                CaseNew.Property__c!= mapVerifyOldCases.get(Case New.Id).Property__c)){
                            
                properties.add(CaseNew.Property__r);
        
             }
        }     
        

        //DML updates if array isn't empty
        IF(properties.size()>0){
          
          update properties;
        
        }      
                        
                   
}        
}

 

 

Here is my trigger - which just populates the variable arrays for my apex class.

 

trigger CaseUpdates on Case (before insert,before update) 
{
         
           //instantiate class
           public PropertyUpdatebyCode  clsPropertyUpdatebyCode=new PropertyUpdatebyCode();

 

           //populate varibles
           clsPropertyUpdatebyCode.lstNewCases = Trigger.new;
           clsPropertyUpdatebyCode.lstOldCases = Trigger.old;

 

           //calls method
           clsPropertyUpdatebyCode.PropertyUpdatebyCode();
           
}

I have a VF page and Controller Extension that allows me to clone a custom object (ProposalFlight__c) record. The ProposalFlight__c record has a lookup field to another custom object, called Geo__c. Using the VF page (which overrides the custom clone button) and the Controller Extension, I am able to clone both ProposalFlight__c and Geo__c at the same time. However, I'm really struggling with creating the unit test for the controller extension.

 

VF Page:

<apex:page standardController="ProposalFlight__c" extensions="ProposalFlightCloneExtension" 
    action="{!cloneRecord}">
    <apex:pageMessages />
</apex:page>

 

Controller Extension (I've replaced the fields that are actually in the queury with (all Fields) just to make it reasier to read here):

 

public class ProposalFlightCloneExtension{
    
    //Variable to hold current record
     ProposalFlight__c currentRecord;
     
     //Standard constructor method
     public ProposalFlightCloneExtension(ApexPages.StandardController controller){
         currentRecord = (ProposalFlight__c)controller.getRecord();
     } 
     
      public PageReference cloneRecord(){
         //Variable to hold the new record
         ProposalFlight__c newRecord;
         Savepoint sp = Database.setSavepoint();
         
         try{
         
             //first clone the Geo Record
             Geo__c clonedGeo;
             
             for(Geo__c relatedGeo: [SELECT (All Fields) FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE id=: currentRecord.id)]){
                 Geo__c newGeo = relatedGeo.clone(false);
                 clonedGeo = newGeo;
             } 
             insert clonedGeo;
             
             //now clone the Proposal Flight
             currentRecord = [SELECT (All Fields) FROM ProposalFlight__c WHERE id=:currentRecord.id];
             newRecord = currentRecord.clone(false);
             newRecord.ApprovalStatus__c = Status.NotSubmitted;
             newRecord.ClonedFrom__c = currentRecord.id;
             newRecord.Geo__c = clonedGeo.ID;
             newRecord.GeoTargetSummary__c = clonedGeo.Text__c;
             insert newRecord;

         }catch(Exception e){
             Database.rollback(sp);
             ApexPages.addMessages(e);
             return null;
         }
         
         return new PageReference('/'+newRecord.id);
     }

}

 

 

My Unit Test so far:

 

@isTest (SeeAllData = True)
private class Test_ProposalFlightCloneExtension{
    
    static testMethod void testProposalFlightClone(){
    
        //create test data
        Account acct = UnitTestFactory.makeAccount();
        Opportunity opp = UnitTestFactory.makeMasterCPMOpp(acct.id);
        ProposalFlight__c pf = UnitTestFactory.makeCPMPF(opp.id);
        Geo__c geo = [SELECT Id FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE Id =: pf.Id)];
        
        //Go to Page
        Test.setCurrentPage(Page.ProposalFlightClone);
        
        //Set Parameters that would be passed in
        ApexPages.currentPage().getParameters().put('Id', pf.Id);
        
        //Instantiate a new controller with all parameters in place
        ProposalFlightCloneExtension ext = new ProposalFlightCloneExtension(new ApexPages.StandardController(pf));
        
        PageReference pageRef = Page.ProposalFlightClone;

    
    }

}

 The unit test passes, but is only covering 12% of the class. It doesn't cover any of the actual cloning logic. If anyone could point me in the right direction I would really appreciate it. Thank you!

 

  • September 05, 2013
  • Like
  • 0

Hi,

 

We are adding tabs to our Account, Contact, Lead and Opportunities pages. We have already added custom pages and used the Apex code to create the tabs.

 

However, the problem we are having is when we are trying to add "Activity History", "Open Activities" or any other objects to our custom tabbed page.

 

The error we get looks like this,

 

 
'activityhistory' is not a valid child relationship name for entity Lead 

 

Here is the code that we use to create tabs and add "Activity History",

 

 

 

      <apex:tab label="Lead Detail" name="LeadDetails" id="tabdetails" styleclass="AcctListStyle">
             <apex:detail relatedList="false" title="true"/>
             
             <apex:relatedList subject="{!lead}" list="activityhistory" />             
      </apex:tab>

 

 

If you could please post a step by step process on how to get this resolved, thanks in advance!

 

  • September 05, 2013
  • Like
  • 0

Hi All,

 

I'm having an issue getting my code coverage for an Apex class i've written above 0.

 

here is the apex class:

 

public class TwilioMMASyncSMS {
	@future (callout=true)
		public static void sendSMS(Set<Id> Ids) {
    		String toNumber = '';
    		String messageBody = '';
    	for (Monitoring_Visit_Bursary__c mvp: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Monitoring_Visit_Bursary__c WHERE id IN :Ids]) {
            if (mvp.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientmvp = TwilioAPI.getDefaultClient();
            	toNumber = mvp.User_ID_Phone__c;
            	messageBody = mvp.SMSBody__c;
            	Map<String,String> params = new Map<String,String> {
                	'To'   => toNumber,
                	'From' => '+14156830489',
                	'Body' => messageBody
             	};
         	TwilioSMS sms = SMSclientmvp.getAccount().getSmsMessages().create(params);
			}
    	}
     	for (School_Termly_Update__c stu: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM School_Termly_Update__c WHERE id IN :Ids]) {
            if (stu.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientstu = TwilioAPI.getDefaultClient();
            	toNumber = stu.User_ID_Phone__c;
            	messageBody = stu.SMSBody__c;
             	Map<String,String> params = new Map<String,String> {
                	'To'   => toNumber,
               		'From' => '+14156830489',
                 	'Body' => messageBody
              	};                 
        	TwilioSMS sms = SMSclientstu.getAccount().getSmsMessages().create(params);
            }
     	}
     	for (Structure_Status_Report__c ssr: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Structure_Status_Report__c WHERE id IN :Ids]) {
            if (ssr.User_ID_Phone__c != null) {
         	TwilioRestClient SMSclientssr = TwilioAPI.getDefaultClient();
             	toNumber = ssr.User_ID_Phone__c;
             	messageBody = ssr.SMSBody__c;
              	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                 	'From' => '+14156830489',
                  	'Body' => messageBody
              	};
        	TwilioSMS sms = SMSclientssr.getAccount().getSmsMessages().create(params);
            }
     	}
         for (New_Cama_Review__c ncr: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM New_Cama_Review__c WHERE id IN :Ids]) {
            if (ncr.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientncr = TwilioAPI.getDefaultClient();
              	toNumber = ncr.User_ID_Phone__c;
              	messageBody = ncr.SMSBody__c;
              	Map<String,String> params = new Map<String,String> {
                  	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
               	};
        	TwilioSMS sms = SMSclientncr.getAccount().getSmsMessages().create(params);
           	}
         }   		
         for (Background_data__c bd: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Background_data__c WHERE id IN :Ids]) {
            if (bd.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientbd = TwilioAPI.getDefaultClient();
             	toNumber = bd.User_ID_Phone__c;
              	messageBody = bd.SMSBody__c;
               	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
               	};
        	TwilioSMS sms = SMSclientbd.getAccount().getSmsMessages().create(params);
            }
         } 
         for (New_Grade_10_Girls__c ng10g: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM New_Grade_10_Girls__c WHERE id IN :Ids]) {
            if (ng10g.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientng10g = TwilioAPI.getDefaultClient();
             	toNumber = ng10g.User_ID_Phone__c;
             	messageBody = ng10g.SMSBody__c;
             	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
              	};           
        	TwilioSMS sms = SMSclientng10g.getAccount().getSmsMessages().create(params);
            }
         }
         for (Monitoring_Visit__c mv: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Monitoring_Visit__c WHERE id IN :Ids]) {
            if (mv.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientmv = TwilioAPI.getDefaultClient();
              	toNumber = mv.User_ID_Phone__c;
             	messageBody = mv.SMSBody__c;
              	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
              	};
       	 	TwilioSMS sms = SMSclientmv.getAccount().getSmsMessages().create(params);
           	}
         }  
         for (Camfed_Annual_data__c cad: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Camfed_Annual_data__c WHERE id IN :Ids]) {
            if (cad.User_ID_Phone__c != null) {
            TwilioRestClient SMSclientcad = TwilioAPI.getDefaultClient();
             	toNumber = cad.User_ID_Phone__c;
             	messageBody = cad.SMSBody__c;
            	Map<String,String> params = new Map<String,String> {
                   	'To'   => toNumber,
                   	'From' => '+14156830489',
                   	'Body' => messageBody
              	};
        	TwilioSMS sms = SMSclientcad.getAccount().getSmsMessages().create(params);
            }  	  			  		
     	}
	}
}

 When writing the test class I figured that I would need to create an example of all the related object records that allow me to get this information (note that SMSBody and User_ID_Phone__c are formula fields).

 

This is the test class that I have written:

 

@isTest
public class TwilioMMASyncSMSTest {
			static testMethod void TwilioMMASyncSMS() {
				String toNumber = '';
    			String messageBody = '';
					// create a country
						Country__c country = new Country__c();
						country.Name = 'test country';
						insert country;
					// create a district
						District__c district = new District__c(); 
						district.Name = 'test';
						district.Country__c = country.id;
						insert district;
					// create a school
						School__c school = new School__c();
						school.Name = 'test';
						school.District__c = district.id;
						insert school;
					// create a contact
						Contact contact = new Contact();
						contact.LastName = 'test';
						contact.District__c = district.id;
						contact.School__c = school.id;
						contact.Country__c = country.id;
						insert contact;
					//create a structure
						Structure__c structure = new Structure__c();
						structure.Country__c = country.id;
						structure.District__c = district.id;
						structure.Chair__c = contact.id;
						structure.School__c = school.id;
						insert structure;
					// create a Monitoring Visit to Bursary
						Monitoring_Visit_Bursary__c mvp = new Monitoring_Visit_Bursary__c();
						mvp.Person__c = contact.id;
						mvp.User_ID__c = 'uk07717417554@gmail.com';
						insert mvp;
					// create school termly update
						School_Termly_Update__c stu = new School_Termly_Update__c();
						stu.School__c = school.id;
						stu.User_ID__c = 'uk07717417554@gmail.com';
						insert stu;
					// create Structure Status Report
						Structure_Status_Report__c ssr = new Structure_Status_Report__c();
						ssr.Structure__c = structure.id;
						ssr.User_ID__c = 'uk07717417554@gmail.com';
						insert ssr;
					// create New Cama Review
						New_Cama_Review__c ncr = new New_Cama_Review__c();
						ncr.Country__c = country.id;
						ncr.District__c = district.id;
						ncr.Graduation_School_Same_District__c = school.id;
						ncr.User_ID__c = 'uk07717417554@gmail.com';
						insert ncr;
					// create Background Data
						Background_data__c bd = New Background_data__c();
						bd.Name = 'DB Test';
						bd.Structure__c = structure.id;
						bd.User_ID__c = 'uk07717417554@gmail.com';
						insert bd;
					// create New Grade 10 Girls
						New_Grade_10_Girls__c ng10g = New New_Grade_10_Girls__c();
						ng10g.school__c = school.id;
						ng10g.User_ID__c = 'uk07717417554@gmail.com';
						insert ng10g;
					// create Monitoring Visit
						Monitoring_Visit__c mv = New Monitoring_Visit__c();
						mv.MSG_Visiting__c = structure.id;
						mv.Primary_Monitor__c = contact.id;
						mv.school__c = school.id;
						mv.tm__c = contact.id;
						mv.User_ID__c = 'uk07717417554@gmail.com';
						insert mv;
					// create Camfed Annual Data
						Camfed_Annual_data__c cad = New Camfed_Annual_data__c();
						cad.school__c = school.id;
						cad.User_ID__c = 'uk07717417554@gmail.com';
						insert cad;
					for (Monitoring_Visit_Bursary__c mvpsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Monitoring_Visit_Bursary__c WHERE id = :mv.id]) {
            			if (mvpsms.User_ID_Phone__c != null) {
            			
            				toNumber = mvpsms.User_ID_Phone__c;
            				messageBody = mvpsms.SMSBody__c;
            					Map<String,String> params = new Map<String,String> {
				                	'From' => '+14156830489',
                					'To'   => toNumber,
                					'Body' => messageBody
             					};
         				
						}
    				}
					for (School_Termly_Update__c stusms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM School_Termly_Update__c WHERE id = :stu.id]) {
            			if (stusms.User_ID_Phone__c != null) {
            				toNumber = stusms.User_ID_Phone__c;
            				messageBody = stusms.SMSBody__c;
             					Map<String,String> params = new Map<String,String> {
                					'To'   => toNumber,
				               		'From' => '+14156830489',
                				 	'Body' => messageBody
				              	};                 
            			}
     				}
     				for (Structure_Status_Report__c ssrsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Structure_Status_Report__c WHERE id = :ssr.id]) {
            			if (ssrsms.User_ID_Phone__c != null) {
         				
             				toNumber = ssrsms.User_ID_Phone__c;
             				messageBody = ssrsms.SMSBody__c;
              					Map<String,String> params = new Map<String,String> {
                 					'To'   => toNumber,
                 					'From' => '+14156830489',
                  					'Body' => messageBody
              					};
        				
            			}
     				}
         			for (New_Cama_Review__c ncrsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM New_Cama_Review__c WHERE id = :ncr.id]) {
            			if (ncrsms.User_ID_Phone__c != null) {
            			
              				toNumber = ncrsms.User_ID_Phone__c;
              				messageBody = ncrsms.SMSBody__c;
              					Map<String,String> params = new Map<String,String> {
                  					'To'   => toNumber,
                  					'From' => '+14156830489',
                  					'Body' => messageBody
				               	};
        				
			           	}
			         }   		
         for (Background_data__c bdsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Background_data__c WHERE id = :bd.id]) {
            if (bdsms.User_ID_Phone__c != null) {
            
             	toNumber = bdsms.User_ID_Phone__c;
              	messageBody = bdsms.SMSBody__c;
               	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
               	};
        	
            }
         } 
         for (New_Grade_10_Girls__c ng10gsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM New_Grade_10_Girls__c WHERE id = :ng10g.id]) {
            if (ng10gsms.User_ID_Phone__c != null) {
           
             	toNumber = ng10gsms.User_ID_Phone__c;
             	messageBody = ng10gsms.SMSBody__c;
             	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
              	};           
        	
            }
         }
         for (Monitoring_Visit__c mvsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Monitoring_Visit__c WHERE id = :mv.id]) {
            if (mvsms.User_ID_Phone__c != null) {
           
              	toNumber = mvsms.User_ID_Phone__c;
             	messageBody = mvsms.SMSBody__c;
              	Map<String,String> params = new Map<String,String> {
                 	'To'   => toNumber,
                  	'From' => '+14156830489',
                  	'Body' => messageBody
              	};
       	 
           	}
         }  
         for (Camfed_Annual_data__c cadsms: [SELECT Id, SMSBody__c, User_ID_Phone__c FROM Camfed_Annual_data__c WHERE id = :cad.id]) {
            if (cadsms.User_ID_Phone__c != null) {
            
             	toNumber = cadsms.User_ID_Phone__c;
             	messageBody = cadsms.SMSBody__c;
            	Map<String,String> params = new Map<String,String> {
                   	'To'   => toNumber,
                   	'From' => '+14156830489',
                   	'Body' => messageBody
              	};
        	
            }  	  			  		
     	}		
	}			
}

 It deploys fine and validates fine just doesn't aid my code coverage for my main class.

 

What am I missing here?

 

Thanks

Dan

Hello,

 

I have a custom email service that is used to track/update some things on cases.  I am having an issue though when parsing text from the email body.  There is a specific string I am looking for in the body that will cause certain updates to happen.  I have the code debug the email body and the two strings I am looking for are there, but the code acts like it is incorrect.

 

The frustrating thing is that this only happens when the email is sent from the original source.  I have a copy of the email and when I forward the message for testing reasons it recognizes the string just fine.  Here is the code for this piece:

string emailType;        
string emailStart = email.plainTextBody.left(325).normalizeSpace();
string initialResponseString1a = 'Thank you for approaching RateGain Customer Support';
string initialResponseString1b = 'We have received your message and logged it in our automated tracking system under the';                
system.debug('---------------------------------> emailStart:  ' + emailStart);
if(emailStart.contains(initialResponseString1a) &&  emailStart.contains(initialResponseString1b)){
    emailType = 'initial response';
}else{emailtype = 'update';}
system.debug('---------------------------------> emailType:  ' + emailtype);

 Here is the debug log of when this is from the original source:

4:00:13.217 (1217711000)|USER_DEBUG|[51]|DEBUG|---------------------------------> emailStart:  Thank you for approaching RateGain Customer Support.  We have received your message and logged it in our automated tracking system under the Ticket # 1029941. This ticket is now being assigned to a Resolution Expert who will analyze this and revert within 4 hours.  _________________________________________________________
14:00:13.217 (1217725000)|SYSTEM_METHOD_EXIT|[51]|System.debug(ANY)
14:00:13.217 (1217753000)|SYSTEM_METHOD_ENTRY|[57]|System.debug(ANY)
14:00:13.217 (1217770000)|USER_DEBUG|[57]|DEBUG|---------------------------------> emailType:  update

 

 

As you can see BOTH strings I am looking for are in there, but the code is still saying emailType = update.  However, when I send the email from my email address the debug says this:

14:24:56.206 (206699000)|USER_DEBUG|[51]|DEBUG|---------------------------------> emailStart:  Thank you for approaching RateGain Customer Support. We have received your message and logged it in our automated tracking system under the Ticket # 1029854. This ticket is now being assigned to a Resolution Expert who will analyze this and revert within 4 hours. ____________________________________________________________
14:24:56.206 (206722000)|SYSTEM_METHOD_EXIT|[51]|System.debug(ANY)
14:24:56.206 (206766000)|SYSTEM_METHOD_ENTRY|[57]|System.debug(ANY)
14:24:56.206 (206809000)|USER_DEBUG|[57]|DEBUG|---------------------------------> emailType:  initial response
14:24:56.206 (206825000)|SYSTEM_METHOD_EXIT|[57]|System.debug(ANY)

 

 

How is this possible.  Is it some sort of formatting with the email from the originating system?  How can I handle that in APEX?

 

Thanks,
Jeremy Stender

 

<apex:page standardController="Opportunity">

<apex:pageBlock title="LineOrder">
<apex:pageBlockTable value="{! Opportunity.Order__r.LineOrder__r}" var="item">
<apex:column value="{! item.name}"/>
</apex:pageBlockTable>
</apex:pageBlock>

</apex:page>

Is it possible to show LineOrders this way?

 

Thanks

Is there any method through which i can get the lookup field object name through id only that comes in that lookup field??

 

Thanks

 

 

Hey I'm trying to correct some old code that is hitting governor limits for when we try and post our trades to SF. The last class we changed to Dynamic Apex and it seems to work fine, so I was hoping someone could help me do it again as I'm not experienced enough yet.

 

Error:

Trades_CascadeAccounts: System.LimitException: Too many code statements: 200001

 

Main Class:

public class Account_RollupTrades {
    public Account[] accountOldList { set; get; }
    public Account[] accountNewList { set; get; }
    public Account_Setting__c setting { set; get; }
    
    public Account_RollupTrades(Account[] accountOldList, Account[] accountNewList) {
        this.accountOldList = accountOldList == null ? new Account[] {} : accountOldList.clone();
        this.accountNewList = accountNewList == null ? new Account[] {} : accountNewList.clone();
        
        this.setting = Account_Setting__c.getInstance();
        this.setting = setting == null ? new Account_Setting__c() : setting;
    }
    
    public void execute() {
        if (setting.Disable_RollupTrades__c == true)
            return;
        
        Account[] accountUpdateableList = new Account[] {};
        
        for(Account accountNew : accountNewList) {
            if (accountNew == null || account.Id == null)
                continue;
            if (accountNew.Rollup_Trades__c != null)
                continue;
            accountUpdateableList.add(accountNew);
        }
        
        execute(accountUpdateableList);
    }
    
    public void execute(Account[] accountList) {
        if (accountList == null || accountList.size() == 0)
            return;
        
        // Reset accounts
        Map<Id, Account> accountListMap = new Map<Id, Account>(accountList);
        
        for(Account account : accountList) {
            account.Total_NIOR_I_Sales__c = 0;
            account.Total_NIOR_I_Shares__c = 0;
            account.YTD_NIOR_I_Sales__c = 0;
            account.YTD_NIOR_I_Shares__c = 0;
            account.QTD_NIOR_I_Sales__c = 0;
            account.QTD_NIOR_I_Shares__c = 0;
            account.MTD_NIOR_I_Sales__c = 0;
            account.MTD_NIOR_I_Shares__c = 0;
            account.PY_NIOR_I_Sales__c = 0;
            account.PY_NIOR_I_Shares__c = 0;
            
            account.Total_NS_REIT_Sales__c = 0;
            account.Total_NS_REIT_Shares__c = 0;
            account.YTD_NS_REIT_Sales__c = 0;
            account.YTD_NS_REIT_Shares__c = 0;
            account.QTD_NS_REIT_Sales__c = 0;
            account.QTD_NS_REIT_Shares__c = 0;
            account.MTD_NS_REIT_Sales__c = 0;
            account.MTD_NS_REIT_Shares__c = 0;
            account.PY_NS_REIT_Sales__c = 0;
            account.PY_NS_REIT_Shares__c = 0;
            
            account.Total_NS_HIT_Sales__c = 0;
            account.Total_NS_HIT_Shares__c = 0;
            account.YTD_NS_HIT_Sales__c = 0;
            account.YTD_NS_HIT_Shares__c = 0;
            account.QTD_NS_HIT_Sales__c = 0;
            account.QTD_NS_HIT_Shares__c = 0;
            account.MTD_NS_HIT_Sales__c = 0;
            account.MTD_NS_HIT_Shares__c = 0;
            account.PY_NS_HIT_Sales__c = 0;
            account.PY_NS_HIT_Shares__c = 0;
            
            account.Rollup_Trades__c = DateTime.now();
        }
        
        // Roll up the trades based on the Resolved Firm Trading ID field
        
        Trades__c[] tradesList = [
            select Dollar_Amount_of_the_transaction__c
                 , Fund_Number__c
                 , Number_of_Shares_of_the_transaction__c
                 , Resolved_Firm_Trading_ID__c
                 , Trade_Date__c
              from Trades__c
             where Resolved_Firm_Trading_ID__c in :accountList
               and Fund_Number__c in ('3910', '3911', '3912')       // NIOR I; NS REIT; NS HIT
               and Dollar_Amount_of_the_transaction__c != null      // prevents null pointers below
               and Number_of_Shares_of_the_transaction__c != null   // prevents null pointers below
               and Trade_Date__c != null                            // prevents null pointers below
               
               // Negative values are ignored for roll-up purposes
               and Dollar_Amount_of_the_transaction__c >= 0
               and Number_of_Shares_of_the_transaction__c >= 0
        ];
        
        
        // Nothing to do?
        if (tradesList.size() == 0)
            return;
        
        // Update accounts
        for(Trades__c trades : tradesList) {
            Account account = accountListMap.get(trades.Resolved_Firm_Trading_ID__c);
            
            if (account == null || trades == null || trades.Trade_Date__c == null)
                continue;
            else if ('3910'.equals(trades.Fund_Number__c))
                processFund_3910(account, trades);
            else if ('3911'.equals(trades.Fund_Number__c))
                processFund_3911(account, trades);
            else if ('3912'.equals(trades.Fund_Number__c))
                processFund_3912(account, trades);
        }
    }
    
    void processFund_3910(Account account, Trades__c trades) {
        system.assert(null != account);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            account.YTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.YTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            account.QTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.QTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            account.MTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.MTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            account.PY_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.PY_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            account.Total_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.Total_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }

    void processFund_3911(Account account, Trades__c trades) {
        system.assert(null != account);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            account.YTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.YTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            account.QTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.QTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            account.MTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.MTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            account.PY_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.PY_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            account.Total_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.Total_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }
    
    void processFund_3912(Account account, Trades__c trades) {
        system.assert(null != account);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            account.YTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.YTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            account.QTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.QTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            account.MTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.MTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            account.PY_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.PY_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            account.Total_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            account.Total_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }
}

 

 

I have a trigger that does multiple processes on the case object.  I seem to be hitting my soql limits on this trigger.  Could someone point me in the right direction of where I might be looping too many statements?  Much appreciated.

trigger BeforeCaseInsert on Case (before insert,before update)
{
    List<String> RecordTypeNameList = new List<String>();
    RecordTypeNameList.add('CR');
    RecordTypeNameList.add('Prod Specialist');
    RecordTypeNameList.add('BenchPress');
    RecordTypeNameList.add('Support');
    
    
    List<RecordType> RecordTypeResult = [SELECT id,Name FROM RecordType WHERE name in: RecordTypeNameList];
    
    Map<String,Id> RecordTypeNameIDMap = new Map<String,Id>();
    
    for(RecordType rt : RecordTypeResult)
    {
        RecordTypeNameIDMap.put(rt.Name,rt.id);
    }
    
 
    private List <Sites__c> sitesF;
    List<Spec_History__c> SpecList = new List<Spec_History__c>();
    
   
    sitesF = new List<Sites__c>([SELECT id, Name, Feedback__c, Account__c, Account__r.Publication_Manager2__c
                                 FROM Sites__c LIMIT 50000]);
    
    
    
    //Create lists for the case team member code
    List<CaseTeamMember> ctm = new List<CaseTeamMember>();
    List<CaseTeamMember> ctmdelete = new List<CaseTeamMember>();
    List<CaseTeamRole>ctrole = [SELECT Name, Id FROM CaseTeamRole];
    Map<String,String>caseteamr = new Map<String,String>{};
        for(CaseTeamRole ct:ctrole){
            caseteamr.put(ct.Name, ct.Id);}
    
    //Create Set of Case Ids where status is Closed
    Set<ID>cid= new Set<ID>();
    
    
    for (Case c : trigger.new) {
        
        if (c.Description != null
            && c.Description != ''
            && c.recordTypeID == RecordTypeNameIDMap.get('Support'))
        {
            for(Sites__c s : sitesF) {
                if(c.Description.contains(s.Feedback__c) && s.Feedback__c != null){
                    c.sites__c = s.id;
                    c.accountId = s.account__c;

                    break;}
            }
        }
        
        if (c.recordTypeId == RecordTypeNameIDMap.get('Prod Specialist')
            && c.JCode__c != null
            && c.JCode__c != ''
           ) {
               for(Sites__c s : sitesF) {
                   if (c.JCode__c == s.Name){
                       c.accountId = s.account__c;
                       c.Sites__c = s.id;
                       break;
                   }
               }
               
           }
        
        // Spec History Code
        if (Trigger.isUpdate) {
            if (c.recordTypeId == RecordTypeNameIDMap.get('CR'))      
            {
                Case oldCase = Trigger.oldMap.get(c.ID);
                if (c.Spec_Image__c != oldCase.Spec_Image__c || c.Spec_pages__c != oldCase.Spec_Pages__c || c.Jcode__c != oldCase.JCode__c || c.Spec_description__c != oldCase.Spec_description__c || c.Configuration_Details__c != oldCase.Configuration_Details__c ) {
                    Spec_History__c newspec = new Spec_History__c ();
                    if (c.Spec_Image__c != oldCase.Spec_Image__c) {
                        newspec.Spec_Image_History__c = oldCase.Spec_Image__c;
                    }
                    if (c.Spec_pages__c != oldCase.Spec_Pages__c){
                        newspec.Spec_pages__c = oldCase.Spec_Pages__c;
                    }
                    if (c.Jcode__c != oldCase.JCode__c){
                        newspec.Spec_Jcode__c = oldCase.JCode__c;
                    }
                    if (c.Spec_description__c != oldCase.Spec_description__c){
                        newspec.Spec_description__c = oldCase.Spec_description__c;
                    }
                    if (c.Configuration_Details__c != oldCase.Configuration_Details__c){
                        newspec.Spec_Config_Details__c = oldCase.Configuration_Details__c;
                    }
                    newspec.Case__c = c.ID;
                    SpecList.add(newspec);
                }
                
            }
        }
        
        if (c.recordTypeId == RecordTypeNameIDMap.get('BenchPress'))
        {
            for(Sites__c s : sitesF) {
                
                if (c.Journal_Code__c == s.id){
                    c.Sites__c = s.id;
                    c.accountId = s.account__c;
                    
                    //         accMap.put(s.account__c,s.Account__r);
                    break;
                }
            }
        }
        
        /**
Following code used to insert case team members using the case manager field
**/
        // Get the id of the old case
        if (Trigger.isUpdate) {
            Case oldCase = Trigger.oldMap.get(c.Id);
            //Delete old case manager from case team
            if(oldCase.Case_Manager__c != null || oldCase.Case_Manager__c == null){
                for(CaseTeamMember ctmrem : [SELECT Id FROM CaseTeamMember WHERE MemberID =: c.Case_Manager__c OR MemberID =: oldCase.Case_Manager__c]){
                    
                    ctmdelete.add(ctmrem);}
            }
            // If the old case manager doesn't equal the new case manager
            if(oldCase.Case_Manager__c != c.Case_Manager__c &&	 c.Case_Manager__c != null){
                
                // Create a list of the members in the case team
                
                // For each of the case managers in ctmlist
                
                
                CaseTeamMember ctmadd = new CaseTeamMember();
                ctmadd.ParentId = c.id;
                ctmadd.MemberId = c.Case_Manager__c;
                ctmadd.TeamRoleId = caseteamr.get('Case Manager');
                
                
                // Add the case manager to the list ctm
                ctm.add(ctmadd);
                
            }  
        }

//add to list of only cases that have been cancelled/declined
        if(c.Status=='Cancelled/declined'){
            cid.add(c.id);}
    }
    if(SpecList.isEmpty()==false){
        insert SpecList;    }
    if(ctmdelete.isEmpty()==false){
        delete ctmdelete;}        
    if(ctm.isEmpty() == false){
        insert ctm;}
    
    List < Opportunity > OppUpdateList = [SELECT Id, StageName from Opportunity WHERE Case__c in : cid AND StageName <> 'Closed - Lost'];
    
    //Set those Opportunities to Closed - Lost
    for (Opportunity oppsupd: oppUpdateList) {
        oppsupd.StageName = 'Closed - Lost';
    }
    update oppUpdateList;
    
}

 

Hi all,

 When I merge account, I want to get the deleted record id and update a field value for the newly merged record.

 

 

trigger accountMerge on Account (after delete) {
public ID MasterRecordIdfield = null;
Account[] acc= Trigger.old; 
MasterRecordIdfield = acc[0].MasterRecordId;
if(MasterRecordIdfield != null && String.valueOf(MasteRecordIdfield).length() >0)
{
Account[] acct = [select Id, name from account where id =:MasterRecordIdField];
for(Account acct:acc)
{
acct.Field_to_update__c = acct.name;
update acct;
}
}
}

 

 

When I execute this, I m getting the following error, I dont know where I am going wrong. Help Please.

 

Apex trigger then.accountMerge caused an unexpected exception, contact your administrator: then.accountMerge: execution of AfterDelete caused by: System.DmlException: Update failed. First exception on row 0 with id 0019000000K7lxGAAR; first error: SELF_REFERENCE_FROM_TRIGGER, Object 0019000000K7lxGAAR is currently in a merge operation, therefore a trigger can not update it.: []: Trigger.then.accountMerge: line 12, column 1

Hi All,

 

I have a test class that was running fine until .  Now I continue to get this error message:

System.DmlException: Update failed. First exception on row 0 with id 006e0000003jL5JAAU; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []

 

I've narrowed down the cause of the issue to our Sharing settings as opposed to a record Id or FLS issue - but I'm stuck there.

 

The sharing settings previously were:

- Private with access granted through heirarchies

- Owner in all internal users shared with all internal users.

 

The sharing were updated to

- Private with access granted through heirarchies

- Type = New Sale (Not Bundled), New Sale (Bundle) with All internal users

- Type = Net Organic with a specific group of roles

 

For the life of me, I cannot figure out why this code is failing with the new sharing model even though the Type field in the opportunity declaration of my test class is specified as "New Sale (Bundle)." The running user does have edit access on their profile and has edit access to the Vertical_Enrollment_Rep field. Just for kicks, if I switch it back to the original sharing settings, the test class passes.

 

 

Here is the code that's failing with the new sharing model:

   static testMethod void shouldCreateTaskOnUpdate() {
		
		Profile enrollmentProfile = [SELECT Id FROM Profile WHERE Name = 'Enrollment'];

		List<user> enrollmentUsers = [SELECT Id FROM User WHERE ProfileId = :enrollmentProfile.Id AND IsActive = TRUE];

		User enrollmentRep;
		
		for( User user : enrollmentUsers ) {

			if( enrollmentRep == null ) {
				enrollmentRep = user;
				continue;
			}
			
			break;
		}
		
		System.assertNotEquals(null, enrollmentRep);
		enrollmentRep = [SELECT Name, Profile.Name FROM User WHERE Id =:enrollmentRep.Id];
		System.debug('-------------------------------CURRENT USER NAME: ' + enrollmentRep.Name);
		System.debug('ENROLLMENT REP PASSED');

		System.debug('Insert Account');
    	Account vendorAccount = new Account(Name = 'Vendor Acct', Status__c = 'Vendor', Type__c = 'Vendor');
    	insert vendorAccount;
    	
    	Go_Forward_PM_System__c goForwardPM = new Go_Forward_PM_System__c (Name = 'Greenway', Status__c = 'Partner', Client_Type__c = 'Channel', 
    		Vendor_Account__c = vendorAccount.Id);
    	insert goForwardPM;
    	
       	Account account = new Account(Name='Test', Status__c='Backlog', Type='Medical Practice', Type__c = 'Medical Practice', Specialty__c = 'General Practice',
            	Go_Forward_PM_System__c = goForwardPM.Id, Number_of_Docs__c = 1, Leaving_Which_Clearinghouse__c = 'Cerner', Customer_Id__c = 'ZYDS3892', 
            	Current_Clearinghouse__c = 'Cerner');     
       	insert account;
		System.debug('Insert Account PASS');
    	
		Opportunity opportunity = new Opportunity ( AccountId = account.Id, Name = 'Test', StageName = 'Won', CloseDate = System.today(), Sales_Commit__c = 'Commit', Claims_Application__c = 'Yes', 
			Demo_Location__c = 'Onsite Demo', Our_Competition__c = 'Availity', Sr_Mgmt_involved_in_Demo__c = 'No', Client_Services_Select_One__c = 'Not Applicable', Type = 'New Sale (Bundle)', No_Enrollment_Needed__c = FALSE, 
			Vertical_Enrollment_Rep__c = null, Kick_Off_Complete_Enrollment__c = null, Vertical_Go_Live_Date__c = null, Never_Going_Live__c = null, Stalled_Vertical_Date__c = null);
		insert opportunity;

		Task[] tasks = [SELECT Id FROM Task WHERE AccountId =:account.Id and OwnerId = :enrollmentRep.id];

		System.assertEquals(0, tasks.size());		

		System.debug('----------------------Start Update!');
		System.runAs(enrollmentRep) {
			test.startTest();
				opportunity.Vertical_Enrollment_Rep__c = enrollmentRep.Id;
				update opportunity;
			test.stopTest();			
		}
		System.debug('-----------------------End Update');

		tasks = [SELECT Subject, ActivityDate, ReminderDateTime, IsReminderSet, RecordTypeId FROM Task WHERE AccountId =:account.Id and OwnerId =: enrollmentRep.Id];

		System.debug('Found tasks: ' + tasks);

		System.assertEquals(1, tasks.size());
		System.assertEquals('Vertical Kick Off Call: ' + account.Name, tasks[0].Subject);
		System.assertEquals(DateTime.newInstance(System.today().addDays(3), Time.newInstance(8, 0, 0, 0)),tasks[0].ReminderDateTime);
		System.assertEquals(True,tasks[0].IsReminderSet);
		System.assertEquals('01230000000cjHy', tasks[0].RecordTypeId);
    }

 

Help!

Whenever I do bulk api uploads to the object referenced in this code I receive an hundreds of emails and failures with the error:

 

 System.LimitException: Too many code statements: 200001

 

any ideas how I can limit/update this apex to prevent this error and allow me once again to upload in bulk.

 

Trigger entitlementTrigger on Entitlement__c (before insert, before update) {
Map<String, String> YearsMap = new Map<String, String>();
Map<String, String> TermsMap = new Map<String, String>();
Map<String, String> DistrictsMap = new Map<String, String>();
Map<String, String> SchoolsMap = new Map<String, String>();
Map<String, String> RecordTypeMap = new Map<String, String>();
for(Entitlement__c e: trigger.new) {
     YearsMap.put(e.Year__c, null);
     TermsMap.put(e.Term__c, null);
     DistrictsMap.put(e.DistrictID__c, null);
     SchoolsMap.put(e.School__c, null);
     RecordTypeMap.put(e.StudentType__c, null);
}
List<District_Entitlement_Sheet__c> DESList = [SELECT Id, Term__c, Year__c, District__c, Sheet_Type__c FROM District_Entitlement_Sheet__c WHERE Term__c in: TermsMap.KeySet() OR Year__c in: YearsMap.keySet() OR District__c in: DistrictsMap.KeySet() OR Sheet_Type__c in: RecordTypeMap.KeySet()];
List<Entitlement_Sheet__c> ESList = [SELECT  Id, Term__c, Year__c, School__c, Sheet_Type__c FROM Entitlement_Sheet__c WHERE Term__c in: TermsMap.keySet() OR Year__c in: YearsMap.KeySet() OR School__c in: SchoolsMap.KeySet() OR Sheet_Type__c in: RecordTypeMap.KeySet()];
//Now that we have the lists populated of any potential matches iterate through trigger list and match
for(Entitlement__c e: trigger.new) {
      for(District_Entitlement_Sheet__c des: DESList){
           if(e.Term__c == des.term__c && e.Year__c == des.Year__c && e.DistrictID__c == des.District__c && e.StudentType__c == des.Sheet_Type__c) {
                 e.District_Entitlement_Sheet__c = des.Id;
           }
      }
      for(Entitlement_Sheet__c es: ESList){
           if(e.Term__c == es.term__c && e.Year__c == es.Year__c && e.School__c == es.School__c && e.StudentType__c == es.Sheet_Type__c) {
                 e.Entitlement_Sheet__c = es.Id;
           }
      }
}
}

 

 

Hi everyone,

In my application I have to create a sale opportunity for each Account selected with the products selected.

So let's resume I got the accountIDs, productIds and I have to create the sale opportunity.

What I don't understand in the schema page on salesforce, it shoes OpportunityLineItem is composed of a Product2 which I can't find with the schema explorer on the IDE.

So how I can link my new OpportunityLineItem to a product ?

Thanks 

Sylvain

Hi 

 

  1. How many rows return by list controller?

Thanks,

I have created an opportunity trigger to send out an email to two separate email address field whenever the stage is Closed Won depending on the Campaign Type. It works perfectly fine but recently when I tried updating a list of 200 opportunity records it gave me an error saying "**Too many code statements 200001**".

 

My code is as follows:

 

trigger SendEmail on Opportunity (after update)
{
Set<Id> accountSet = new Set<Id>();
Set<Id> marketSet = new Set<Id>();

for (Opportunity o : Trigger.new) {
accountSet.add(o.Accountid);
marketSet.add(o.Campaignid);
}
Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Name, Phone, PersonMobilePhone, PersonEmail from Account where id in :accountSet] );
map<Id, Campaign> marketMap = new Map<Id, Campaign>([SELECT Name, Parent_Market__c from Campaign where id in :marketSet]); 
for (Opportunity o : Trigger.new) {
if(o.Campaign_Type__c != Null && o.StageName != Null){
for (Integer i = 0; i < Trigger.old.size(); i++) {
Opportunity old = Trigger.old[i];
Opportunity nw = Trigger.new[i];
Account theAccount = accountMap.get(o.AccountId);
Campaign Market = marketMap.get(o.CampaignId);
String userName = UserInfo.getUserName();

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); 
List<String> toAddresses = new List<String>();
List<String> ccAddresses = new List<String>();
ccAddresses.add('test@test.com');
mail.setToAddresses(toAddresses); 
mail.setCcAddresses(ccAddresses);
mail.setSenderDisplayName('Campaign Information');

mail.setSubject(+ theAccount.Name + ' is Closed Won');

mail.setReplyTo('noreply@salesforce.com');
//Body of the Email
mail.setHtmlBody(
'<font face="Times" size="3">'+
'<table width="100%">'+
'<tr width="0%">'+
'<td rowspan="0">'+
'</td>'+
'<td>'+
'<h2>Account is closed won notification</h2>'+
'</td>'+
'</tr>'+
'</table>'+
'<br/>'+
'<b>Stage:</b> ' + o.StageName + '<br/>' + '<br/>' +
'<b>Opportunity Number:</b> ' + o.Name + '<br/>' +
'<b>Amount Paid:</b> $' + o.Amount + '<br/>' + '<br/>' +
'<b>Account Name:</b> ' + theAccount.Name + '<br/>' +
'<b>Phone:</b> ' + theAccount.Phone + '<br/>' +
'<b>Mobile:</b> ' + theAccount.PersonMobilePhone + '<br/>'+
'<b>Email:</b> ' + theAccount.PersonEmail + '<br/>'+
);

// Send Email if it isCampaign1 and Closed Won
if((nw.StageName !=old.StageName) || (nw.Campaign_Type__c !=old.Campaign_Type__c)){ 
if(o.Campaign_Type__c.equals('Campaign1')){
if(o.StageName.equals('Closed Won') ){
toAddresses.add(o.Email__c);
try {
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
catch(Exception ex) { }
}

}
}
// Send Email if it is Campaign2 and Closed Won
if((nw.StageName !=old.StageName) || (nw.Campaign_Type__c !=old.Campaign_Type__c)){ 
if(o.Campaign_Type__c.equals('Campaign2')){
if(o.StageName.equals('Closed Won')){
toAddresses.add(o.Email2__c);
toAddresses.add(o.Email1__c);
try {
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
catch(Exception ex) { }
}
}
} 
} 
}
} 
}

 

Any help would be appreciated.

Thanks

1. On 2013-08-02 I installed Eclipse IDE V28.0.0.201307091110 
2. Built new project that included Approval Processes; I selected a single approval process using add/remove metadata
3. Eclipse IDE constructed package.xml incorrectly for this Approval Process: 

Name: 'Approve: Quote' 
API name: 'Approve_Quote' 

Resulting package.xml built as follows: 

 

 

<Package xmlns="http://soap.sforce.com/2006/04/metadata"> 
   <types> 
      <members>Approval_Request__c.Approve%3A Quote</members> 
      <name>ApprovalProcess</name> 
   </types> 
<version>28.0</version> 
</Package>

 

 

This is incorrect, Eclipse can't locate this approval process as the API name was not used 

The correct package.xml (after I edited it) is: 

<Package xmlns="http://soap.sforce.com/2006/04/metadata"> 
   <types> 
     <members>Approval_Request__c.Approve_Quote</members> 
     <name>ApprovalProcess</name> 
   </types> 
<version>28.0</version> 
</Package>

 

Ticket with SFDC Premier Support filed

 

Post made here on Boards to advise others in case they have similar use case

This post defines the problem and will be followed with the solution in the reply

 

Problem: Using the Codeshare Project Force.com for Google Visualization: http://developer.force.com/codeshare/apex/projectpage?id=a06300000030w9LAAQ

 

Line Chart displays fine in IE8 and Firefox, but fails with 'google not defined' in Chrome

 

For reference, I'm showing the VF page plus associated VF component. Note the many javascript window.alert debugging statements that I used.

 

The VF page:

<apex:page standardController="Account" showheader="false">
	<html>
	   <body>	
		<c:PurchaseHistoryAndFutureRenewals width="1200" height="400" 
		            hAxisTitle="{!JSENCODE('Timeline')}" 
		            vAxisTitle="{!JSENCODE('IgnoreMe')}"/>  
	   </body>
	</html>
</apex:page>

 The VF Component:

<apex:component controller="GoogleChartsCustomController" >
	<apex:attribute name="jsonData" description="This is the chart data from the controller" type="string" assignTo="{!GoogleChartablePurchaseHistoryAndFutureRenewals}"/>
	
	<!-- Doc for this component is here: http://code.google.com/apis/visualization/documentation/gallery/linechart.html  -->
	
	<apex:outputPanel id="chart_div">
		<script type="text/javascript" src="http://www.google.com/jsapi"></script> 
		<script type="text/javascript">
			window.alert('Script starts');
			try {
				google.load("visualization", "1", {packages: ["corechart"]});
				window.alert('google visualization package loaded');
				google.setOnLoadCallback(drawLineChart);
				window.alert('google callback set');
				}
			catch (err) {
				window.alert("exception="+err.message);
				}

 			function drawLineChart() {
  				var data = new google.visualization.DataTable( eval( '({!GoogleChartablePurchaseHistoryAndFutureRenewals})' ) );
  				window.alert('datatable evaluated'); 
				var chart = new google.visualization.LineChart(document.getElementById('{!$Component.chart_div}'));
			  	chart.draw(data, {	hAxis: 	{title: "{!hAxisTitle}"}, 
			  						vAxis: 	{title: "{!vAxisTitle}"}, 
			  						height: {!height},
			  						width: 	{!width}
			  						}
			  				);
			  	window.alert('chart drawn'); 								  
 			}
		
		</script>
	</apex:outputPanel>
</apex:component>

 Many dead ends followed trying to figure out why (especially since I'm more of an APEX/stock VF guy than a Javascript guy)

 

and the solution is ....

 

 

Here is VF page Foo at V26.0:

<apex:page >
  <h1>Congratulations</h1>
  This is your new Page
</apex:page>

 If you go to the browser address bar and type URL: https://cs12.salesforce.com/apex/foo

 

Windows 7

  • Firefox - page displays successfully
  • Chrome - page displays successfully
  • IE8 8.0.7601.17514 - 'Internet Explorer cannot display the webpage'

Mac OS X

  • Firefox - page displays successfully
  • Safari - page displays successfully

 

If I create the identical VF page in a different sandbox (cs7.salesforce.com), the page displays successfully in IE 8 (!?!)

 

My production users are also experiencing similar issues using IE - various VF pages in na5 WILL NOT display in IE but WILL display in Firefox/Chrome

 

  • Clearing cache/cookies in IE has no effect
  • Private browsing in IE 8 (which disables all extensions and add-ons) has no effect on the result
  • Resetting IE settings to defaults had no effect
  • Accessing cs12.salesforce.com through company VPN and not through company VPN had no effect

 

I'm very puzzled here as the VF page is bog standard; works in Firefox/Chrome/Safari; I have IE 8 (Windows 7) configured to defaults

  • page display successfully in cs7 IE8
  • page fails to display in cs12 IE8

Both sandboxes have the same Winter 13 critical update enabled so AFAIK, sandboxes are identical (both at Winter 13)

 

 

Note - this post is more along the lines of providing a reference to others rather than a request for specific help

 

Business use case:

  1. Excel files are emailed to dozens of external users around the world. Data source is SFDC Sobject data. Recipients are not SFDC users.
  2. Users update the Excel files, save as CSV and email to SFDC inbound Email Service.
  3. Inbound Email Services parses CSV and updates SObjects 

Problem(s):

  1. Any accented characters such as ã as in São Paulo will update the SFDC SObject as S�o Paulo or
  2.  'BLOB is not a valid UTF-8 string' error is thrown in the Inbound Email Handler

Why does this happen?

  1. SFDC uses UTF-8 encoding for characters
  2. Excel can happily open .xlsx files created from UTF-8 data, and, if you have the right fonts on your system,, will happily display the characters as you would expect
  3. HOWEVER, Excel can not export to CSV in UTF-8. It just can't.
  4. The CSV file is encoded using your machine's default character set, perhaps Windows-1252 or ISO-8859-1 or something else
  5. When you attach the CSV to an outbound email, it will be received by the SFDC Inbound Email Handler as either a text or binary attachment (I believe this depends on the email client)
  6. If received as a text attachment, a character encoded in Windows-1252 or ISO 8859-1 (1 byte) will be thought of by the Inbound Email Handler APEX as UTF-8
  • Example: the character ž is hex 9E or, in bits 10011110.  However, if you look at the UTF-8 spec (summarized) you see that any byte starting with a '1' bit always means that UTF-8 thinks it will be a multi-byte description of the character.  Even worse, there is no UTF-8 valid encoding for 1001... so, SFDC replaces the 9E with the UTF-8 fallback code U+FFFD - and this displays as �.

7. If received as a binary attachment, an attempt to use the method toString() on the attachment's Blob body fails for the same reason as #6 above -  'BLOB is not a valid UTF-8 string'

 

Now, how to work around this problem?

 

A. There are various ways to get a CSV into UTF-8. Unfortunately, they all require the user to do unnatural acts:

  • Excel > CSV, then open CSV in Notepad++ and encode in UTF-8, then Save
  • Copy/paste values from Excel into a Google Docs or Open Office spreadsheet and use those tools to save as CSV, encoded to UTF-8
  • Install an Excel addin that can save as CSV to UTF-8

B. What most definitely does not work is to do a Save As in Excel (as of Excel 2010) and use the Tools dialog on the Save As window - Web Options | Encoding | Save this document as Unicode (UTF-8). Excel ignores this for CSV saves.

 

What also doesn't work in Excel is to Save as Unicode Text as this is UTF-16.

 

C. Various redesign options:

  • Only process updates for fields that can't take accented characters (like, say, changing Stage or some other picklist-driven field)
  • Use try-catch around the Messaging.Inboundemail.BinaryAttachment toString() method, and, if UTF-8 error, send a message back to the sender with detailed instructions on how to create a UTF-8 CSV (or route to the admin)
  • Don't use CSV files for update payloads; build a Sites application, use SFDC-SFDC, SFDC partner portal
  • Open up your SFDC org to the external users with very tight security (relevant especially for updates to Std Objects) - this avoids the whole CSV update path altogether
  • Redo your InboundEmailHandler to accept .xlsx files. Use an APEX callout to a third party service that can parse the Excel .xlsx binary and send it back as a UTF-8 CSV.  I have not tried this.
  • Have your recipients install an Excel addin that creates UTF-8 output such as http://jaimonmathew.wordpress.com/2011/08/23/excel_addin_to_work_with_unicode_csv/ (I have not tried this)
  • Train your recipients to use the Google Docs/Open Office route mentioned above under (A).
  • Have your recipients in Excel do a Save As 'Xml Spreadsheet 2003' - this will in fact preserve your accented characters (I haven't checked Asian languages but European languages seem to work OK). Then change your inbound email parser to parse XML files. This is a monolithic text file (unlike the zipped OOXML files MSFT adopted in Office 2007 which will be useless to the Apex code in the Inbound email handler).

 

  • Example using Save As XML Spreadsheet 2003 - the character ž appears in the output XML file (seen through a hex editor) as C5BE - the UTF-8 ž character!

 

I'm curious what other solutions folks have come up with

Winter 13 anomaly 

 

I have a test class Foo that among other things:

 

* inserts a ContentVersion

* inserts a ContentWorkspaceDoc

* updates the ContentVersion with custom field values and tags

 

If I login to the Winter13 sandbox using credentials for system administrator X, select class Foo and Run Tests - the tests pass fine

 

If I use Ecliipse IDE Version 24.0.0.201202291629 also logged in as user X and do Apex Test Runner on the very same class Foo, I get the error:

System.DmlException: Update failed. First exception on row 0 with id 068V00000008ILuIAM; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []

 

where the ID is the ID of the ContentVersion record and the DML is on the Update of the ContentVersion record

 

These tests all ran fine in Eclipse prior to the sandbox being upgraded to Winter 13

 

Here's what I don't get:

Doesn't Eclipse IDE simply instruct the sandbox cloud to execute the test class Foo, all execution occurs in the sandbox cloud, and the results/log are merely passed back to Eclipse?

 

Given that the Ecliipse project uses the same credentials as those I use to UI login to the Force.com platform, the Eclipse test execution should execute the same as running the test via a Force.com Run Tests button click. True?

 

What could be different here? Does the Winter 13 sandbox code somehow execute the test class submitted by Eclipse with different context than when I execute it from the Force.com UI?  I've never seen this before and I've been running this APEX class in Eclipse successfully since V19.0

 

When usiing the Eclipse IDE Force.com plugin, and you do 'New Apex Class", you can choose from three templates:

 

  • Default
  • Test_Class
  • Inbound_Email_Service

 

How do I add to this list with my own templates?  There is no templates option in Eclipse 3.6 Window | Preferences |<search on template> within the Force.com section

 

I can see that the aforementioned templates live in this path on my (Windows XP) machine:

C:\eclipse\configuration\org.eclipse.osgi\bundles\812\1\.cp\templates ..

 

and I can add a template in that folder and it will appear as a choice -- yet this doesn't seem like the right way to do this

 

Using IDE  version 20

Scenario: mass edit selected items in a related list (Opportunities of an Account) - how to get the mass edit page to sort same as selected items?

 

Step 1: Select using check boxes 3 Opportunities in the Account related list of Opportunities

Oppo Mass Edit

Step 2: Display the mass edit page

oppo mass edit 2 of 2

 

RESULT: the mass edit page is not sorted in same order as the related list (Month 02 - Month 01 - Month 03 rather than Month 03 - Month 02 - Month 01)

 

Why would this be?

 

Here is the VF code for the page:

<apex:page standardController="Opportunity" recordSetVar="opps">
<script>function setFocusOnLoad() {}</script> <!-- disables focus from going to first field calendar picker -->
<apex:form >
    <apex:sectionHeader title="Change fields on monthly billing opportunities"/>
    <apex:pageBlock mode="edit">
        <apex:pagemessages />
        <apex:pageBlockButtons >
            <apex:commandButton value="Save" action="{!save}"/>
            <apex:commandButton value="Cancel" action="{!cancel}"/>
        </apex:pageBlockButtons>
        <apex:pageBlockSection title="Change to new value">
            <apex:inputField value="{!Opportunity.Opportunity_Source__c}"/>
            <apex:inputField value="{!Opportunity.NextStep}"/>
            <apex:inputField value="{!Opportunity.Remarks__c}"/>
        </apex:pageBlockSection>
        <apex:pageBlockSection title="Changes apply to these selected items">    
            <apex:pageBlockTable value="{!selected}" var="o" cellspacing="20px">
                <apex:column value="{!o.name}"/>
                <apex:column value="{!o.stagename}"/>
                <apex:column value="{!o.closeDate}"/>
                <apex:column value="{!o.amount}"/>
                <apex:column headerValue="Service Start Date">
                    <apex:inputField value="{!o.SnS_Contract_Start_Date__c}"/>
                </apex:column>    
                <apex:column headerValue="Service End Date">
                    <apex:inputField value="{!o.ContractEndDate__c}"/>
                </apex:column>
            </apex:pageBlockTable>        
        </apex:pageBlockSection>
    </apex:pageBlock>   
</apex:form>

</apex:page>

 

So, here is the detailed question:

 

A. The pageBlockTable uses the {!selected} value which maps to the getSelected() method on the StandardSetController so it correctly picks up the three selected items. There is no controllerExtension.

 

B. The VF documentation Winter 12 version pg 68 states: "When you are using a standard list controller, the returned records sort on the first column of data, as defined by the current view, even if that column is not rendered."  Well, wouldn't the current view be the related list Account>Opportunities? and that first column is Opportunity Name so why is the pageBlockTable not sorted by Opportunity.Name?  It appears to sort randomly as if out of a map.

 

I realize this could be solved with APEX controllerextension but fidelity to the selected items should be preserved without recourse to APEX.

 

Thoughts?

Summer 11 introduced Log Filters on the Apex Class Detail Page -- Our sandbox was just upgraded to Summer 11.

 

I go to class Foo that is currently at Version 18.0, override Log Filters to set APEX CODE to 'INFO'; then Run Tests on Class Foo.  The debug log for the run uses these settings:

 

 

18.0 APEX_CODE,FINE;APEX_PROFILING,FINE;DB,INFO;VALIDATION,INFO;WORKFLOW,FINEST

 I don't want APEX_CODE FINE, I want it INFO.  How do I do this?

 

 

 

 

 

 

 

Scenario:

 

  1. VF Controller Extension interacting with a VF page containing an inputFile component.
  2. User fills in form; including filename
  3. User clicks commandButton that calls action method on VF controller
  4. Validation rules within action method execute within context of try - DML statements - catch block
  5. Errors caught and set on page via Apexpages.addMessage(...) method call
  6. SFDC displays page with Internal Server Error !?!

Solution in succeeding post

I'm using Eclipse IDE 3.5 and set Apex Code Log Level in the lower right pane to 'Debug'. According to the Apex Spring 10 Developer's Guide - 

 

"METHOD_ENTRY and METHOD_EXIT events are logged at FINEST level"  

 

So, what gives? If I set the logging level to 'DEBUG' for APEX Code, why do I still see METHOD_ENTRY and METHOD_EXIT events in my Eclipse IDE debug log?  Needless to say, the debug logs become voluminous forcing me to break up test methods into separate classes to avoid the dreaded 'maximum debug size reached, log truncated' message

 

Do all my components needed to be upgraded to the latest API level (18.0)? for the debug log settings to take effect?

 

thanks in advance

Problem:

 

You have a VF page that you want to output as Excel but the line breaks in your TextArea fields cause Excel to create new rows at each line break rather than preserve the line breaks within the cell as if you had used ALT-ENTER (or your line breaks are lost altogether and the text is run on with no breaks)

 

Example:

 

SFDC TextArea field contains:

"Line 1

Line 2"

 

(or "Line 1\nLine 2")

 

Your output in Excel should be one row with the cell preserving the line breaks but you either:

 

a) get two rows, broken at the line break

b) one row but the line break is lost and the text is run-on

 

Solution follows in the next post

Problem statement:

 

When APEX inserting OpportunityShare records, you get DML Exception: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY

 

Why does this happen?

 

The obvious reasons are:

 

  • OpportunityShare.OpportunityId is for an invalid Opportunity (or not an opportunity at all)
  • Running user doesn't have access to the Opportunity in OpportunityId



But if neither of these are the case...what else could it be?

 

ANSWER:

 

You can not insert OpportunityShare records for the current owner of the record.  You'll need to modify the Apex code to see if the current owner is the same as OpportunityShare.UserOrGroupId.  If it is, then don't insert.  You can still create OpportunityTeamMember records for that user but not OpportunityShare.  Who the current user is will depend if you are doing the OpportunityShare Dml statement in a before trigger, after trigger, VF controller, or API.

 

Although I haven't tested this, I presume the above applies to AccountShare and CaseShare objects as well.

I have an APEX ControllerExtension class which overrides the Edit button.  To make life easy for me, I use a Dynamic SOQL statement to fetch all columns from the Opportunity sObject so they are available for display in the VF page should I need them

 

That is, I create a SOQL statement of the form:

 

'select field1,field2, ...fieldn from Opportunity where id = :oppId'

 

One of my fieldx is a formula field using this formula:

 

 

'First name Last name= ' & $User.FirstName & ' ' & $User.LastName & BR() &
'User.UserType= ' & TEXT($User.UserType) & BR() &
'UserRole.Name=' & $UserRole.Name & BR() &
'UserRole.PortalType=' & TEXT($UserRole.PortalType) & BR() &
'Profile.LicenseType=' & TEXT($Profile.LicenseType) & BR()

If this fieldx is included in either a dynamic SOQL or static SOQL expression, at run time, when executed from the Partner Portal by a partner Portal user, I get:

 

System.Exception: Internal Salesforce.com Query Error

and not much else.

 

Obviously, there is something this formula field does that messes up the SOQL call -- although the field displays fine on the standard controller user interface detail page (View).

 

I selectively commented out parts of the formula to determine which parts cause the Internal Salesforce.com Query Error

 

TEXT($User.UserType) - If present in the formula field, Internal Salesforce.com Query Error occurs

TEXT($UserRole.PortalType)  - If present in the formula field, Internal Salesforce.com Query Error occurs

 

 

All other expressions in the formula field don't cause an error.

 

I can work around this particular problem but in general, any sObject field should be queryable through SOQL and not depend on the formula expression.  Why it works through the standard controller UI and not through a controller extension SOQl (static or dynamic) is unknown.

 

Hopefully, this will help someone out in the future

 

 

 

 

 

 

 

I finally got around to starting development in Sandbox of using APEX + Controllers + VF to manipulate CRM Content objects but I immediately ran into a roadblock where perhaps you can help:

1.      

  1. Force.com IDE is at V16.0 because SFDC chose not to release a version 17 IDE; we apparently have to wait until Spring 10 (Version 18).    
  2. Because of this, the Schema that shows in Eclipse IDE is only V16.0 objects and thus excludes the CRM Content objects.
  3. Therefore, I can’t develop any code to use the CRM Content objects because the Schema isn’t aware of them.
  4. I tried changing the package.xml to <version> tag from <version>16.0</version>
    to <vesion>17.0</version> but this made no difference.
  5. Is there some other trick I am missing here?  Or must I wait until Spring 10?  (using the WSAPI is not an answer here)

Thanks

 

Eric

A few days ago, I was running Eclipse 3.3 (Europa) + Summer 09. 

In the IDE I observed that (finally), apex tags on VF pages were no longer marked as 'unknown tag' with squiggly yellow underline

Then, I installed Eclipse 3.4 (Ganymede) + Summer 09.  Now, the IDE shows apex tags in VF pages as 'unknown tag' with the squiggly yellow underline.  

 

What did I do wrong here? Is the SFDC Summer 09 plugin Eclipse version dependent?

 

Exact details

 

Eclipse 3.4.2

SFDC V16.0.0.0.200906151227

Message Edited by crop1645 on 09-17-2009 11:36 AM
Message Edited by crop1645 on 09-17-2009 11:36 AM
Message Edited by crop1645 on 12-18-2009 02:52 PM

I've written a custom controller that exploits the StandardSetController class to return a page of records and allow pagination.

 

VF controller has three (relevant) methods:

 

getPage()  - returns List of records in current pageset (pagesize = 10)

previousPage() - executes the previous() method on the standard set controlller object

nextPage() - executes the next() method on the standard set controller object

 

The StandardSetController is constructed using a Database.getQueryLocator per the doc

 

setCtlr = new ApexPages.StandardSetController(

Database.getQueryLocator(

[Select id, name, Account__r.name from Foo__c where id in :fooIdSet]));

When I set up my APEX test method:

 

1.  Insert 11 rows into database  //works ok

2.  Assert that getPage() returns 10 rows  // assertion passes

3.  Execute nextPage() on the controller

4.  Assert that getPage() returns 1 row (the 11th)

 

Here's the problem: step #3 fails because VF comes back with:

 

System.VisualforceException: Modified rows exist in the records collection!

 

I checked the creation datetime and lastmodify datetime just prior to executing Step3 and all is OK, the records haven't mysteriously been changed underneath.

 

I get the same error (in a non-Sites test whilst logged in as admin and simply executing the VF page in the browser.

 

What would cause this error?

Message Edited by crop1645 on 04-08-2009 05:12 PM
Message Edited by crop1645 on 04-08-2009 05:14 PM

Note - this post is more along the lines of providing a reference to others rather than a request for specific help

 

Business use case:

  1. Excel files are emailed to dozens of external users around the world. Data source is SFDC Sobject data. Recipients are not SFDC users.
  2. Users update the Excel files, save as CSV and email to SFDC inbound Email Service.
  3. Inbound Email Services parses CSV and updates SObjects 

Problem(s):

  1. Any accented characters such as ã as in São Paulo will update the SFDC SObject as S�o Paulo or
  2.  'BLOB is not a valid UTF-8 string' error is thrown in the Inbound Email Handler

Why does this happen?

  1. SFDC uses UTF-8 encoding for characters
  2. Excel can happily open .xlsx files created from UTF-8 data, and, if you have the right fonts on your system,, will happily display the characters as you would expect
  3. HOWEVER, Excel can not export to CSV in UTF-8. It just can't.
  4. The CSV file is encoded using your machine's default character set, perhaps Windows-1252 or ISO-8859-1 or something else
  5. When you attach the CSV to an outbound email, it will be received by the SFDC Inbound Email Handler as either a text or binary attachment (I believe this depends on the email client)
  6. If received as a text attachment, a character encoded in Windows-1252 or ISO 8859-1 (1 byte) will be thought of by the Inbound Email Handler APEX as UTF-8
  • Example: the character ž is hex 9E or, in bits 10011110.  However, if you look at the UTF-8 spec (summarized) you see that any byte starting with a '1' bit always means that UTF-8 thinks it will be a multi-byte description of the character.  Even worse, there is no UTF-8 valid encoding for 1001... so, SFDC replaces the 9E with the UTF-8 fallback code U+FFFD - and this displays as �.

7. If received as a binary attachment, an attempt to use the method toString() on the attachment's Blob body fails for the same reason as #6 above -  'BLOB is not a valid UTF-8 string'

 

Now, how to work around this problem?

 

A. There are various ways to get a CSV into UTF-8. Unfortunately, they all require the user to do unnatural acts:

  • Excel > CSV, then open CSV in Notepad++ and encode in UTF-8, then Save
  • Copy/paste values from Excel into a Google Docs or Open Office spreadsheet and use those tools to save as CSV, encoded to UTF-8
  • Install an Excel addin that can save as CSV to UTF-8

B. What most definitely does not work is to do a Save As in Excel (as of Excel 2010) and use the Tools dialog on the Save As window - Web Options | Encoding | Save this document as Unicode (UTF-8). Excel ignores this for CSV saves.

 

What also doesn't work in Excel is to Save as Unicode Text as this is UTF-16.

 

C. Various redesign options:

  • Only process updates for fields that can't take accented characters (like, say, changing Stage or some other picklist-driven field)
  • Use try-catch around the Messaging.Inboundemail.BinaryAttachment toString() method, and, if UTF-8 error, send a message back to the sender with detailed instructions on how to create a UTF-8 CSV (or route to the admin)
  • Don't use CSV files for update payloads; build a Sites application, use SFDC-SFDC, SFDC partner portal
  • Open up your SFDC org to the external users with very tight security (relevant especially for updates to Std Objects) - this avoids the whole CSV update path altogether
  • Redo your InboundEmailHandler to accept .xlsx files. Use an APEX callout to a third party service that can parse the Excel .xlsx binary and send it back as a UTF-8 CSV.  I have not tried this.
  • Have your recipients install an Excel addin that creates UTF-8 output such as http://jaimonmathew.wordpress.com/2011/08/23/excel_addin_to_work_with_unicode_csv/ (I have not tried this)
  • Train your recipients to use the Google Docs/Open Office route mentioned above under (A).
  • Have your recipients in Excel do a Save As 'Xml Spreadsheet 2003' - this will in fact preserve your accented characters (I haven't checked Asian languages but European languages seem to work OK). Then change your inbound email parser to parse XML files. This is a monolithic text file (unlike the zipped OOXML files MSFT adopted in Office 2007 which will be useless to the Apex code in the Inbound email handler).

 

  • Example using Save As XML Spreadsheet 2003 - the character ž appears in the output XML file (seen through a hex editor) as C5BE - the UTF-8 ž character!

 

I'm curious what other solutions folks have come up with

When usiing the Eclipse IDE Force.com plugin, and you do 'New Apex Class", you can choose from three templates:

 

  • Default
  • Test_Class
  • Inbound_Email_Service

 

How do I add to this list with my own templates?  There is no templates option in Eclipse 3.6 Window | Preferences |<search on template> within the Force.com section

 

I can see that the aforementioned templates live in this path on my (Windows XP) machine:

C:\eclipse\configuration\org.eclipse.osgi\bundles\812\1\.cp\templates ..

 

and I can add a template in that folder and it will appear as a choice -- yet this doesn't seem like the right way to do this

 

Using IDE  version 20

Problem statement:

 

When APEX inserting OpportunityShare records, you get DML Exception: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY

 

Why does this happen?

 

The obvious reasons are:

 

  • OpportunityShare.OpportunityId is for an invalid Opportunity (or not an opportunity at all)
  • Running user doesn't have access to the Opportunity in OpportunityId



But if neither of these are the case...what else could it be?

 

ANSWER:

 

You can not insert OpportunityShare records for the current owner of the record.  You'll need to modify the Apex code to see if the current owner is the same as OpportunityShare.UserOrGroupId.  If it is, then don't insert.  You can still create OpportunityTeamMember records for that user but not OpportunityShare.  Who the current user is will depend if you are doing the OpportunityShare Dml statement in a before trigger, after trigger, VF controller, or API.

 

Although I haven't tested this, I presume the above applies to AccountShare and CaseShare objects as well.

Hello,

I'm trying to share an Opportunity from Org1 Sandbox to Org2 Sandbox. Connection is configured on both sides with auto-accept enabled, Opportunity StageName, Name, CloseDate the only fields published/subscribed to.

This works fine when done manually; "forward this opportunity" (status "Active (sent)"/PNRC.Status=Sent ), however it fails when sharing programatically (via a Trigger on Opportunity insert), status is "Pending (sent)"/PNRC.Status=Invite.
Notes:
- No Invite emails to notify me of an incoming Opportunity share.
- There are no validation rules on the target org that would cause it to fail, as proven by the manual sharing working.
- No errors or useful information in the logs.
- Programatic sharing of a custom object works OK. 

Can anyone suggest a next step for diagnosing and resolving this problem? Let me know if you need any more information.

thanks,
David.
Hello,

I'd like to roll up summary a field that is currently a formula. However, i'm under the understanding that this isn't possible natively through salesforce at the moment.
So i figured i'd just copy the field that is a formula into a new field where it isn't a formula and roll that up. I think this will work... however it's the copying/field update that i'm having an issue with.
It seems as though field updates can only be done with workflows that are triggered when a record is created or edited. i'm not looking for it to be live. it at least have it updated whenever a different field (in the same object or not) doesn't equal 0.
How can i do this? Apex?

Robert

Today we’re excited to announce the new Salesforce Developers Discussion Forums. We’ve listened to your feedback on how we can improve the forums.  With Chatter Answers, built on the Salesforce1 Platform, we were able to implement an entirely new experience, integrated with the rest of the Salesforce Developers site.  By the way, it’s also mobile-friendly.

We’ve migrated all the existing data, including user accounts. You can use the same Salesforce account you’ve always used to login right away.  You’ll also have a great new user profile page that will highlight your community activity.  Kudos have been replaced by “liking” a post instead and you’ll now be able to filter solved vs unsolved posts.

This is, of course, only the beginning  and because it’s built on the Salesforce1 Platform, we’re going to be able to bring you more features faster than ever before.  Be sure to share any feedback, ideas, or questions you have on this forum post.

Hats off to our development team who has been working tirelessly over the past few months to bring this new experience to our community. And thanks to each of you for helping to build one of the most vibrant and collaborative developer communities ever.
 

I wrote the code below hoping I can redirect once a Task is saved based on a checkbox.  If checked, user is redirected to the a new Opportunity in edit mode screen.  Not checked, just save the task.  I still have to put in the code to update the check to uncheck.  I can not get the page to redirect.  What am I missing?

 

Trigger:

 

trigger CreateNewOpty on Task (after insert) {

for(Task ta: Trigger.new){

if(ta.Create_Opportunity__c==true){

NewOptyRedirect obj = new NewOptyRedirect();
obj.Redirect(ta.Id);
}


}

 

Apex Code:

 

Public Class NewOptyRedirect {

public PageReference Redirect(string TaskId) {

String str='';
List<Task> taskList = [Select AccountId, Business_Segment__c, Description, Information_Discussed__c, Purpose_of_Call__c, Region__c, Test_Products__c From Task where id=: TaskId];
for(task t : taskList){
str='/006/e?retURL=%2F006%2Fo&accid='+replaceStr(t.AccountId) +'&opp3=CALL LOG OPPTY&opp5='+replaceStr(t.Purpose_of_Call__c)+'&00NG0000008u5yH='+replaceStr(t.Information_Discussed__c)+'&00NG0000008u5xd='+replaceStr(t.Test_Products__c )+'&0NG0000008vezX_lkold='+replaceStr(t.Information_Discussed__c)+'&00NG0000008vezX=Info Discussed: '+replaceStr(t.Information_Discussed__c)+' Comments: '+ replacestr(t.Description)+'&00NZ0000000cv0r='+ replacestr(t.Region__c)+replacestr(t.Business_Segment__c)+'&00NZ0000000cv0m='+replacestr(t.Business_Segment__c);
}

system.debug('here in the apex code-------------'+str);
//PageReference pageRef = new PageReference('http://www.google.com').view();
PageReference r= new PageReference('/apex/RedirectOpportunity');
r.setRedirect(true);
return r;

}

public String replaceStr(String s){
if(s==null) s='';
return s.replace('&', '%26');
}

}

Hi,

 

I wonder if we can we use email templates in apex class for sending emails?

 

Thanks.

Mayank

 

 

  • November 27, 2013
  • Like
  • 0

Hello All recently this error came up, i have not done anything but create a new trigger on opportunity. Any Idea Why this would fire off if my trigger is after update

 

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, OpportunityLineItemUniqueID: execution of BeforeUpdate

caused by: System.LimitException: Too many SOQL queries: 101

Trigger.OpportunityLineItemUniqueID: line 7, column 1: []

 

Trigger:

trigger OpportunityLineItemUniqueID on OpportunityLineItem (before insert, before update) {
    Set<Id> OpportunityIDs = new Set<Id>();
    for (OpportunityLineItem oli : Trigger.New) {
        OpportunityIDs.add(oli.OpportunityId);
    }
    
    Map<Id, Opportunity> Opportunities = new Map<Id, Opportunity>([SELECT Id, OrderId__c FROM Opportunity WHERE Id in :OpportunityIDs]);
    
    for (OpportunityLineItem oli : Trigger.New) {
        Opportunity opp = Opportunities.get(oli.OpportunityId);
        if (opp == null) continue;
        if (opp.OrderId__c == null || opp.OrderId__c == '') continue;
        if (oli.Sequence__c == null || oli.Sequence__c == '') continue;
        
        oli.ScheduleId__c = opp.OrderId__c + '.' + oli.Sequence__c;
    }
}

 

Hi,

 

I did some code that doing callout.It works and I planned to put in trigger based on the requirement.But when I put it inside trigger it required me to put @future in the callout method.So I did that, but my method no longer works.I suspect it due @future because when I run at Apex Execute it not able to return value but when I remove @future it return it successfully.I am not sure why this happen? Any idea?

 

Here the snippet of my code 

 

for(User us : mapUserToProcess.values()){

   system.debug('@email== '+us.email);//this one is return the value
   getUserByEmail(us.email);
   String strXML = returnStr;

}


@future(callout=true)
       static void getUserByEmail(string email)

    {
        String baseUrl = url+'/2.0/admin/users/'+email;
        GetAccessToken();
        
        system.debug(' baseUrl for getUserByEmail  '+ baseUrl );

        HTTPRequest request = new HTTPRequest();              
        request.setEndpoint(baseUrl);
        String authorizationHeader = 'WRAP access_token=' + accessToken;
        request.setHeader('Authorization', authorizationHeader);
        request.setHeader('Content-Type', 'application/json');
        request.setMethod('GET');
        request.setTimeout(120000);

        HTTP http = new HTTP();
        HTTPResponse response =  http.send(request);
        
        if(response.getStatusCode()!=200){
           returnStr=response.getStatusCode() +' : '+  response.getStatus();
           errorCode=response.getStatusCode();
           errorMessage=returnStr;
         }
        
        else {
        
           returnStr=response.getBody();
        
        }
        
        system.debug(' returnStr  '+ returnStr);
    }

 If I removed @future, it will go into the getUserByEmail and retrieve the returnStr value.But if I put @future, it not even print out the system.debug and not even return value for returnStr.

 

Thanks.

 

 

 

 

  • November 26, 2013
  • Like
  • 0

Background:

We have a terrible .net/mssql quoting solution that we are planning to do away with.  We are shopping it around at the same time also trying to see if we can duplicate all of the "required" functionality with some custom SFDC objects/classes/controllers/pages.  The one functionality that I'm not to sure on how to replicate (becuase of govenor limits) is the use of SQL lookup tables.  To keep it simple, we have 4 tables Quote, QuoteLine, Product, PriceAgreements.  The way the quote line validation works is that for every quote line (up to 500 lines) we look to see if the product on that line is in the PriceAgreements table and if it is we enforce contractual pricing constraints.  I tried to do this quickly in SF (described below) and quiclkly ran into a governor limit of no more than 100 SOQL queries.

 

SFDC setup

We have a custom quote (Q) and quote line (QL) obect.  The QL has a lookup relationship to the standard salesforce Product (P) object.  We also have a priceagreement (PA) object that also has a lookup to P.  When I call a class to validate all lines on the quote I'm looping over a list of QL and querying the PA object to determine if the product on the quote line is in the priceagreement object.  Once I get to 100 quote lines it craps out.  I can't help but think this could be elegantly designed but that is where I am stuck.

 

Any ideas on a way to be able to perform this validation line by line without hitting a govenor limit.  We are flexible with our object structure as it is just a proof of concept so I'll take anything!!

 

Thanks,

Justin Howell

Hello,

 

I am looking to develop a trigger that will fire when a Lead is created.  It will need to convert the lead to an Account and Contact (no Opportunity) but also search to see if there are existing Accounts/Contacts that it would be merged with.  The code I have below converts the leads, but it doesn't check for existing Accounts or Contacts.  Is there a way to modify it so that it will merge the Lead into any existing Accounts/Contacts or create new Accounts/Contacts if no existing ones are found?

 

trigger LeadConvert2 on Lead (after update) {
List<Account> accList = new List<Account>();
List<Contact> conList = new List<Contact>();
List<Opportunity> oppList = new List<Opportunity>();

//Bulkified
for (Lead lead : Trigger.new) {
if (lead.isConverted == false) //to prevent recursion
{

Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(lead.Id);

LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);


Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());


Account acc = new Account(id=lcr.AccountId);
accList.add(acc);

Contact con = new Contact(id=lcr.ContactId);
conList.add(con);

Opportunity opp = new Opportunity(id=lcr.OpportunityId);
oppList.add(opp);

}
}

update accList;
update conList;
update oppList;
}

  • November 13, 2013
  • Like
  • 0

i have created a visualforce page diplaying set of fields data in columns :-

My Column  :-

 

<apex:column headerValue="Total Price(USD)">                           

  <apex:repeat value="{!varOpp.opp.OpportunityLineItems}" var="PrdLst" rendered="{!if(varOpp.opp.OpportunityLineItems.size>0 , true, false)}" >                                   

<apex:outputField value="{!PrdLst.TotalPrice}"/><br/>                                  

<apex:param value="{!convertCurrencyWithApexCode}"/>                             

</apex:repeat>                                              

</apex:column>

 

Now, I'm getting the data in AUD 450,000.00 (USD 455,843.92) format where i want to display only USD 455,843.92

  • November 13, 2013
  • Like
  • 0

I have a visual force page with inline editing enabled.  It works great when a record exists, however I can't seem to get the page to not be inline editiable when no record exists.  I've tried changing the mode to just edit or detail when no record exists but it doesn't seem to be working. 

 

What I would like is when the page loads, if there is a record then inline editing should be enabled, if no record exists then it shouldn't.

 

I have a feeling that I'm going to have to disable each individual field when no record exists.

 

 

  • November 13, 2013
  • Like
  • 0

 

Any suggestions why this couls be happening?

Thanks!!!

 

 

 

 

<script>
	function updateStatus(selectedCode){  
	alert(" Testing 1 >>>>    "+selectedCode);   
	updateStatusActionFunction(selectedCode);
	alert("Testing 2 >>    "+selectedCode); 
	}
</script>

// Doesn't set the selectedCode as seen in the alert above
// as a result the class in the controller doesn't get invoked.. it doesn't even male it to the class.
<apex:actionFunction name="updateStatusActionFunction" action="{!showStdReqs}" rerender="stdrs,cdTrck"> <apex:param name="jobSelected" assignTo="{!jobSelected}" value="selectedCode"/> </apex:actionFunction> <apex:pageblockSection columns="2" title="CT" id="cdTrck"> <apex:pageBlockSectionItem > <apex:outputLabel value="Job Code" for="jc"/> <apex:outputPanel layout="block" styleClass="requiredInput"> <apex:outputPanel layout="block" styleClass="requiredBlock"></apex:outputPanel> <apex:inputField value="{!ctEmpl.Job_Code__c}" id="jc" onchange="updateStatus(this.value)"/> </apex:outputPanel> </apex:pageBlockSectionItem> ... </apex:pageblockSection> </apex:pageBlock> <apex:pageBlock title="New Requirements" > <apex:pageBlockTable value="{!stdReqs}" var="s" id="stdrs" width="100%" columns="2" columnsWidth="100px, 100px"> <apex:column headerValue="Requirement" value="{!s.Requirement__c}"/> <apex:column headerValue="Category" value="{!s.CT_Category__c}"/> </apex:pageBlockTable> </apex:pageBlock><br/> // CONTROLLER public String jobSelected { get; set; } public Pagereference showStdReqs(){ } }

 

Hi all,

I want to know if my problem is possible.

This is the scenario : I receive an email in my Mail service and i store it in a personnal object : Mail.

But, i want to see my object in an application.

So i wanted to know if it is possible to send an URL from my Apex Class to my application for use it. Is it possible ?  If it is, how can i do it ?

 

Sorry i am new in salesforce and sorry for my english not well.

I have some custom visualforce dashboard components. Everything looks great when a user is on the page, however when the dashboard is emailed the section where these components should be has a message "this component can't be displayed in emails".

 

Anyone with any thoughts as to a solution or work around for this?

Hi All,

In my org Google doc is enabled. Now, I am trying to pull standard 'Add Google Doc' button in my custom Visual force page by tweaking the HTML and JS code behind it. Good thing is that I am able to pull the button and its four dropdown values i.e 'New Document', 'New Spreadsheet', 'New Presentation' and 'Add Existing' and onclick of any of the above, a popup is also coming same as standard popup. 

 

Problem:
When I click 'Create Google Doc' button from popup window a URL is generated and after 1 or 2 second of processing, it redirecting me to home page where as in standard popup, on click of button it process and redirect me to email login page.

My URL:
https://cs15.salesforce.com/_ui/core/google/docs/GoogleDocAuthenticate/d?denied=%2F_ui%2Fcore%2Fgoogle%2Fdocs%2FGoogleDocDenied%2Fd&next=%2F_ui%2Fcore%2Fgoogle%2Fdocs%2FGoogleDocSuccess%2Fd%3Fmethod%3D0%26docName%3DTestBlankFile%26parentId%3Da0Ie00000077ERc%26docType%3DDOCUMENT%26secret%3D13584911

Standard URL:
https://cs15.salesforce.com/_ui/core/google/docs/GoogleDocAuthenticate/d?denied=%2F_ui%2Fcore%2Fgoogle%2Fdocs%2FGoogleDocDenied%2Fd&next=%2F_ui%2Fcore%2Fgoogle%2Fdocs%2FGoogleDocSuccess%2Fd%3Fmethod%3D0%26docName%3DTestBlankFile%26parentId%3Da0Ie00000077ERc%26docType%3DDOCUMENT%26secret%3D28374059

 

Please advise, if anyone has done this before.

 

Thanks

Hi everyone,

 

I hate just throwing up code and saying "what's wrong with it?" but I am not an experienced programmer and I just can't find the issue. So I am hoping someone more experienced will find what is wrong. I am getting the "Argument 1 cannot be null" error from the following code. It is supposed to be an image viewer for images saved as case attachments (something I wish SF had standard BTW).

 

The funny thing is, the code below works on another object with a different page....so, go figure...

 

Here is the controller class

 

public class ImageViewController
{
    private final SObject so;
    private List<Photo> myPhotos = new List<Photo> ();
    
    
    public ImageViewController (ApexPages.StandardController controller)
    {
        this.so = controller.getRecord ();
        fetchPhotos ();
    }

    public class Photo
    {
        String id;
        String url;
        String name;
        
        public Photo (String ipId, String ipName)
        {
            id   = ipId;
            url  = '/servlet/servlet.FileDownload?file=' + id;  // This is the standard SFDC manner to "download" attachments.
            name = ipName;
        }
        
        public String getId ()
        {
            return id;
        }
        
        public String getUrl ()
        {
            return url;
        }
        
        public String getName ()
        {
            return name;
        }
        
    }

    private void fetchPhotos ()
    {
        myPhotos.clear ();  // Empty list
        
        for (Attachment a : [Select Id, Name, ContentType From Attachment Where ParentId = :so.Id])
        {   
            if (!a.Name.endsWith ('tif')) // Don't let TIFs get compared, as these can't be viewed by the viewer.
            {  
                if (a != null && (a.ContentType != '' || a.Id != '' || a.Name != '')) // If no data in the field, skip. 
                {
                    try
                    {
                        if (a.ContentType.contains ('image/'))  // Only add images except TIFs to the list, ignore all other types
                        {
                            myPhotos.add (new Photo (a.Id, a.Name));
                        }
                    } 
                    catch (Exception e)
                    {
                        ApexPages.addMessages(e);
                        Exception e1;
                        ApexPages.addMessages(e1);
                    }
                }
            }
        }
            
    }
                               
    public List<Photo> getPhotos ()
    {
        return myPhotos;
    }         
        
}

 

And this is the page

 

<apex:page standardController="Case" extensions="ImageViewController" showHeader="false" sidebar="false" standardStylesheets="false">
    
    <apex:styleSheet value="{!URLFOR($Resource.picbox,'picbox.css')}"/> 
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"/> 
    <apex:includeScript value="{!URLFOR($Resource.picbox,'picbox.js')}"/>
    
    
          <script>
               if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
                    jQuery(function($) {
                        $("a[rel^='lightbox']").picbox({/* Put custom options here */}, null, function(el) {
                        return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
                        });
                    });
               }
               
         </script>        
  
           <apex:messages />

          <apex:repeat value="{!Photos}" var="p">
                <a rel="lightbox-viewer" href="{!p.url}"  title="{!p.name}" id="{!p.name}">
                     <img width="150" height="150" alt="{!p.name}" src="{!p.url}" title="{!p.name}" />
                </a>
              
           </apex:repeat>

      
</apex:page>
                

 Any help will be appreciated.

 

Regards,

 

Scott

I have an output field in a pageBlock section and I am trying to make the value red. The field is Amount on opportunity but I am using it as a proxy variable to hold a currency total. Any idea why my styles aren't working?

Code:
<apex:pageBlockSectionItem >
<apex:outputLabel value="Total NSP Amount" for="nsptotal"/>
<apex:outputField value="{!masterDiscount.Amount}" id="nsptotal" style="color: red; font-weight: bold"/>
<apex:pageBlockSectionItem >

Thanks,
Jason