Friday 11 November 2016

How to run the schedule a class in every five mins

Here is the cron expression to do so.


System.schedule('Schedule Job Name 2', '0 00 * * * ?', new Schedulerclassname());
System.schedule('Schedule Job Name 3', '0 10 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 4', '0 15 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 5', '0 20 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 6', '0 25 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 7', '0 30 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 8', '0 35 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 9', '0 40 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 10', '0 50 * * * ?', new Schedulerclassname());
System.schedule('SSchedule Job Name 11', '0 55 * * * ?', new Schedulerclassname());

Wednesday 15 June 2016

System.FinalException: Sobject rows does not allow errors:

Sometimes we need to show error message from trigger using add error method. This post is all about what are the challenge i faced to display error message.
My requirement is showing error message if an opportunity which is not linked to contact are updated.As we know opportunitycontactrole is junction object which will relate both opportunity and contact. 
So It is so simple, I went for Opportunity beofore update.
trigger OpportunityBeforeUpdate on Opportunity (before update) {       
       OpportynitySequesncecontroller.beforeUpdate();
}
public class OpportynitySequesncecontroller {
      public void static beofeUpdate(){     
               // others logic are there cos many operation might be there on before update
              OpportynityManagement .validateOppty(trigger.newmap)
      }
}
public class OpportynityManagement {
      public void static validateOppty(Map<Id,Opportunity> newOpptyMap){     
               // logic to show error 
      }
}
OpportynityManagement .validateOppty(trigger.newmap) wiil throw error like below 
Error Error: Compile Error: Method does not exist or incorrect signature: OpportunityManagement.validateOppty(Map<Id,SObject>) 



To resolve this error we need to change way of invocation 
public class OpportynitySequesncecontroller {
      public void static beofeUpdate(){     
               // others logic are there cos many operation might be there on before update
              map<Id,Opportunity> newOpptyMap = (map<Id,Opportunity>)trigger.newMap;
              OpportynityManagement .validateOppty(newOpptyMap )
      }
}
Now this the method where adderror method is used.
public static void validateOppty(map<Id,Opportunity> newOpptyMap){
Id SalesOpsRecordTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Test Sales Opportunity').getRecordTypeId();
list<Opportunity> listOfOpportunity;
if(!newOpptyMap.keyset().isEmpty()){
listOfOpportunity = [SELECT id,(SELECT id FROM opportunitycontactroles) FROM opportunity WHERE recordtypeid =:SalesOpsRecordTypeId AND Id IN :newOpptyMap.keyset()];
for(Opportunity opp:listOfOpportunity){
if(opp.opportunitycontactroles.size() == 0 ){
opp.get(opp.id).addError('Oppotunity can not be modified since it is not having any contacts');
}
}
}
 
}

This code will be complied successfully, but when we update an oppty we can get this exception 
To resolve the above issue method needs to be modified.
public static void validateOppty(map<Id,Opportunity> newOpptyMap){
Id SalesOpsRecordTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Test Sales Opportunity').getRecordTypeId();
list<Opportunity> listOfOpportunity;
if(!newOpptyMap.keyset().isEmpty()){
listOfOpportunity = [SELECT id,(SELECT id FROM opportunitycontactroles) FROM opportunity WHERE recordtypeid =:SalesOpsRecordTypeId AND Id IN :newOpptyMap.keyset()];
for(Opportunity opp:listOfOpportunity){
if(opp.opportunitycontactroles.size() == 0 && newOpptyMap.containskey(opp.id)){
newOpptyMap.get(opp.id).addError('Oppotunity can not be modified since it is not having any contacts');
}
}
}
 
}

Sunday 8 May 2016

How to add list of records to a map?

We all know map is very much required in SFDC, As a developer we should be familiar with map uses. This post is all about to add list of records to a map.

Map<Id,Account> account_map =  new Map<Id,Account>();
public static void addinglisttoMap(List<Account> accList){

for(Account acc:accList){
account_map.put(acc.id,acc);
}

Normally we used to do like above, where processing time will be more(CPU execution time will be more) because we are iterating over a for loop to construct a map. 

I will tell you the best way to construct the map where we can avoid iteration. 

public static void addinglisttoMap(List<Account> accList){

Map<Id,Account> account_map =  new Map<Id,Account>(accList);
}

Advantages- 
Processing time will be very less
No of character in apex class is also less. 

Hope it will be helpful. 

Keep coding and exploring :)  

Order Of Execution In Salesforce


Thursday 17 March 2016

How to convert any standard time to PST ?

As we already know based on user local and company info date time will be displayed by default.
However we need to convert date time from one format to another. Below is some code snippet for this .

DateTime CurentTime = system.now();
String TimeZones = '(GMT-07:00) Pacific Daylight Time (America/Los_Angeles)';
List<String> lststrsplit = TimeZones.substring(12,TimeZones.length()).split('\\(',2);
System.debug('Printing--lststrsplit-'+lststrsplit);
string strTimeZone = lststrsplit[1].substring(0,lststrsplit[1].length()-1);
System.debug('Printing--strTimeZone-'+strTimeZone);
system.debug(CurentTime+'abc#');
string strCurrentTime = CurentTime.format('YYYY-MM-dd HH:mm:ss', strTimeZone);
Datetime dateCurrentTime = Datetime.valueof(strCurrentTime);
System.debug('Printing--dateCurrentTime-'+dateCurrentTime);


Thursday 10 March 2016

How to Parse date in SFDC?

Date format used to vary from system to system.

In SFDC it is like YYYY-MM-DD -2016-03-10 00:00:00

Lets say date format is DD/MM/YYYY in other system, how will we store such date foramt ?

String s = '15/08/2014';
date dt = Date.Parse(s);
System.debug('Printing--today date -'+system.today());

System.debug('Printing---'+dt);

Out put will be

11:25:10.11 (12471791)|USER_DEBUG|[3]|DEBUG|Printing--today date -2016-03-10 00:00:00
11:25:10.11 (12560905)|USER_DEBUG|[5]|DEBUG|Printing---2014-08-15 00:00:00


Friday 4 March 2016

How to format the Currency/number field ?

Sometimes we have to format the currency field based on user need. Here is code snippet which will help you to format the value.

<apex:outputText   value="{0, number, ###,##0.00}">
        <apex:param value="{!objectref.fieldname__c}" />

</apex:outputText>

Monday 29 February 2016

How to avoid this error while running test class "FIELD_CUSTOM_VALIDATION_EXCEPTION, Attempt to de-reference a null object: []"

This post is all about how efficiently custom settings can be used in the class so that we can avoid null pointer exception while running test class with seealldata is false.

As per the best practice concern, we should not use SeeAlldata is true in all the test class.If we wont use that attribute then we need to create all the test data(custom setting record and object record ) in the test class. We might not aware of all the custom setting which will be required to be inserted because they will be refereed in the trigger of some other object which is not really required to be executed.

Normally we use custom setting like below 

 Boolean ischecked = customsettingname__c.getInstance('RecordName').IsChecked__c ;

If we wont insert record name as "RecordName" in the custom setting customsettingname__c in test class , then we will come across this issue   FIELD_CUSTOM_VALIDATION_EXCEPTION, Attempt to de-reference a null object: []"

To avoid such issue we need to use custom setting like below 

Map<String, customsettingname__c> mcs = customsettingname__c.getAll();
System.debug('Printing--'+mcs );

if(mcs.keyset().size()>0 && mcs.containskey('RecordName'))
{
Boolean ischecked = customsettingname__c.getInstance('RecordName').IsChecked__c;
System.debug('Printing--'+ischecked);
}

How to create portal user in apex class?

I think we must have faced difficulty to create portal user in apex class. 

Below are the errors we might have faced. 

System.SObjectException: Field is not writeable: User.IsPortalEnabled 
System.SObjectException: Field is not writeable: User.Contact 

This post is just to tell how to create portal user. We already know that first we need to create Contact and Account , ensure the Account is a partner account, then create a user that points to the contact.

Still same error will come. 

Solution-
To make a partner portal account, we need to ensure the account's owner has the correct values in the UserRoleId and ProfileId fields.
To make a partner user, any user is ok. Simply ensure the user's profile is a Portal User profile. Then you can specify a value for its ContactId field.

Below is the code 

//Create portal account owner
UserRole portalRole = [Select Id From UserRole Where PortalType = 'None' Limit 1];
Profile profile1 = [Select Id from Profile where name = 'System Administrator'];
User portalAccountOwner1 = new User(
UserRoleId = portalRole.Id,
ProfileId = profile1.Id,
Username = System.now().millisecond() + 'test2@test.com',
    Alias = 'batman',
Email='bruce.wayne@wayneenterprises.com',
EmailEncodingKey='UTF-8',
Firstname='Bruce',
Lastname='Wayne',
LanguageLocaleKey='en_US',
LocaleSidKey='en_US',
TimeZoneSidKey='America/Chicago'
);
Database.insert(portalAccountOwner1);

//Create account
Account portalAccount1 = new Account(
Name = 'TestAccount',
OwnerId = portalAccountOwner1.Id
);
Database.insert(portalAccount1);
   
//Create contact
Contact contact1 = new Contact(
    FirstName = 'Test',
    Lastname = 'McTesty',
AccountId = portalAccount1.Id,
    Email = System.now().millisecond() + 'test@test.com'
);
Database.insert(contact1);
   
//Create user
Profile portalProfile = [SELECT Id FROM Profile WHERE Name LIKE '%Portal User%' Limit 1];
User user1 = new User(
Username = System.now().millisecond() + 'test12345@test.com',
ContactId = contact1.Id,
ProfileId = portalProfile.Id,
Alias = 'test123',
Email = 'test12345@test.com',
EmailEncodingKey = 'UTF-8',
LastName = 'McTesty',
CommunityNickname = 'test12345',
TimeZoneSidKey = 'America/Los_Angeles',
LocaleSidKey = 'en_US',
LanguageLocaleKey = 'en_US'
);
Database.insert(user1);

Thursday 18 February 2016

How to split a string into a multiple parts from a common character ?

We may need to split a string into multiple parts from common characters to store it in a set which can be used later for comparison. 

I came across one scenario  like ,I was getting some string which was containing three parts separated by ":"  and I had to compare with custom settings record, I was not sure which part of the string will be match with custom settings record. So I split the string and stored in the set.

Below is some sample code:-

String s = 'Another Person : ChildLine Volunteer Administrator : None';
String s2;
set<String> set_string = new set<String>();
while(s.contains(':')){
s2 = s.substring(0,s.indexof(':')+1);
set_string.add(s2.substring(0,s2.length()-1));
s = s.remove(s2);
}
set_string.add(s);
System.debug('Printing---set_string '+set_string);


Keep learning and sharing...

How contains key method works ? Does it allow partial matches or exact matches ?

This might be very simple, Even I was also thinking as the method name is "containskey" then it should return true if partial matches, unfortunately it is not like that. "Containskey" method will return true only if key is exact match.

It is also case sensitive. Below is some code snippet

map<string,string> test = new map<string,string>();
test.put('abc123','GM');
system.debug('Exact matches -abc123 -'+test.ContainsKey('abc123'));---- True
system.debug('Partial matches-123--'+test.ContainsKey('123')); --- False
system.debug('Partial matches-abc--'+test.ContainsKey('abc')); --- False
system.debug('Case sensitive matches-ABC123-- '+test.ContainsKey('ABC123')); --- False




Friday 12 February 2016

COMPILE ERROR: Invalid initial type List for Map

As we already know map will be very useful while writing code.

How will we create map<Id,Account> ?

Usually we will do using put method of map

map<Id,Account> map_Account = new map<Id,Account>();
for(Account acc:[Select id,name from account]){
    map_Account.put(acc.id,acc);


Instead of iteration we also can do other way for batter performance.
map<id,Account> account_map = new map<Id,Account>([select id,name from account]);
system.debug('printing-----'+account_map );

Now lets go for little advance, instead of static query what if want to use dynamic query like below

map<id,Account> account_map = new map<Id,Account>(database.query(sQuerry));
system.debug('printing-----'+account_map );

we will get an error message like "COMPILE ERROR: Invalid initial type List<SObject> for Map<Id,Account>"



To address above error we can use like 

map<id,sObject> account_map = new map<Id,sObject>(database.query(sQuerry));

Whenever we have to get some value from map we have to type cast to account that's all.

if(account_map.contains('Accountid') ){
Account acc = (Account)account_map.get(Accountid);
}

Keep exploring and sharing...

Thursday 11 February 2016

How to show help text in a vf Page?

Below is code to show 

 <apex:outputPanel id="msgBelowHeader" Styleclass="container_12 clearfix" rendered="{!isPreDistributorVisible}">
                <div style="padding-left: 50px;">
                <b>Your Preffered Distiributor is {!con.account.Preferred_Distributor__c} </b>
                <apex:outputPanel rendered="{!HelpInstructions !=null}">
                <span class="helpButton" id="example-_help">
                <img src="/s.gif" class="helpOrb" style="position: initial;"/>         
                   <script>sfdcPage.setHelp('example','{!HelpInstructions}');</script>
                </span>  
                </apex:outputPanel>
                </div>
            </apex:outputPanel>

Declare a variable HelpInstructions in the class to populate help text to make dynamic also we can add html style sheet to that variable.

KEEP EXPLORING ... 

Tuesday 2 February 2016

How to Invoke approval process from a custom button

In some scenario we have to decided approver as dynamically. Say who will be the first approver and who is the second. 

In that case create create lookup field (First_Approver__c, Second_Approver__c)to user as approver and those field will be used on creating approval steps of approval process . 

Aprroval process 

Approval Steps 




Now the question is how first_approval__c field will be populated ? 

We need to populate those field as instantly I mean just before going to approval process.

Approach - We created a custom button (Content source is java script) and from button code called a method which will update all the approvers and returns true for successful update, Then we are calling approval process.

Class - 
global class YourClass { 

webservice static Boolean MethodForSettingApprover(Id recordId){
       Boolean isUpdated = false;
  try{
//Update the approvers 
isUpdated = true;
  }
  Catch(Exception ex){
System.debug('Printing exception===='+ex.getmessage());
  }
  return isUpdated;
}
}

Button Code - 
{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")} 
function SubmitForApproval() 
var confirmed=confirm("Do you want to continue submitting for approval?"); 

if (confirmed==true) 
var resAppclass = sforce.apex.execute("YourClass","MethodForSettingApprover",{recordId"{!YourObject.Id}"});
var approval;
var processRes;
if(resAppclass == 'true'){
approval = new sforce.ProcessSubmitRequest();
approval.objectId = "{!YourObject.Id}";
processRes = sforce.connection.process([approval]);
}

alert('ProcessRes' + processRes); 
}


Monday 25 January 2016

Attempt to de-reference a null object Issue in SOQL Querry

Attempt to de-reference a null object is common issue, this issue occurs when particular value will be null and we are trying get that value.

I am sharing one scenario where i also faced same issue.

 String MSORecordTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Managed Sales Opportunity').getRecordTypeId();  

map<Id,Opportunity> map_Opportunity = new map<id,Opportunity>([SELECT id,Stagename FROM Opportunity WHERE name = 'test Oppty'  AND recordtypeid = :MSORecordTypeId.substring(0,15)]); 
System.debug('Printing map==='+)map_Opportunity ;
 if(map_Opportunity ! = null){
   
    Opportunity oppty = map_Opportunity.get('OpportynityId');
}

I got error on the line (Opportunity oppty = map_Opportunity.get('OpportynityId');) Because map_Opportunity is having empty value when query filter condition got unsatisfied which is not null so obliviously if condition satisfied. 

To avoid such issue we need to add condition below 

 if(map_Opportunity.keyset().size() > 0){
}

Keep Exploring and sharing more and more .. :)

Monday 11 January 2016

How to Invoke Opportunity Trigger when Opportunity Contact Role Created ?

As we already know Opportunity and contact are related through the junction object OpportunityContactRole and when OpportunityContRole created there wont be any update event to Opportunity. In that case how will we invoke opportunity trigger ?

How will we perform some action when an opportunity is linked to contact?

Possibly answer would be via workflow or trigger. Unfortunately we wont to able to write trigger on OpportunityContactRole nor workflow.

Below is workaround for that scenario.

  • Create  Visual-force page.
  • Create a temp field on Opportunity.
  • Add that vf page on opportunity layout.
  • Set height and width as zero so that it wont be displayed on opportunity layout. 
After OpportunityConRole created, it returns back to Opportunity layout that means inline vf page will be loaded by which one action method will be invoked to update temp field on opportunity.

Once that field is updated, obliviously Opportunity Trigger will be executed.
 

<apex:page standardController="Opportunity" extensions="OppTriggerInvoked" action="{!updateoppty}" />

public with sharing class OppTriggerInvoked {
    public Opportunity opp;
    public OppHelper( ApexPages.StandardController stdController ) {
        opp = ( Opportunity )stdController.getRecord();        
    }
    public void updateoppty(){
        OppTriggerInvoked .updateopptyRecord( opp.Id );    
    }
    @future public static void updateopptyRecord( Id oppId ) {
        Opportunity opp = new Opportunity (id = oppId );
        opp.Is_Updated__c =  true;
        update opp;
    }
}