Showing posts with label Apex. Show all posts
Showing posts with label Apex. Show all posts

Friday, May 9, 2014

Calculate Nth Business Day using Apex in Salesforce.com

It's been a year since I've posted anything on my blog. I've been busy with a lot of custom development on force.com. :)

You might run into a situation where you have to calculate the Nth working days from a specified date.
You will find this post very useful to calculate Nth business day from a given date.

My client has a Service Level Agreement (SLA) requirements in which they need to act on customer complaints within N business days depending upon the severity.

So I came up with the following apex code to determine the Nth business day from a given date. (This APEX CODE Utilize the Holiday object.)
It's pretty straight forward, and it might come in handy for you.

To setup holidays Go to : Administrative setup > Company Profile > Holidays> add few entries e.g. 26th May 2014 >Memorial Day

Apex code is as below:

 //to calculate Nth business day 
    public static Date calculateNthWorkingDay(Date fromDate, Integer N){

         //Query hoildays from Org  
                List<Holiday> holidays=[Select StartTimeInMinutes, Name, ActivityDate From Holiday ];

                Date NthDay = fromDate; 
                
                for(Integer k=0;k<N ;k++ ){
                    if(checkifWorkDay(NthDay.addDays(1),holidays)){                        
                        NthDay = NthDay.addDays(1);
                    } 
                    else
                    {
                      NthDay = NthDay.addDays(1);
                      K--;
                    }
                }

                return NthDay;//send Nth Business day

      }

    //To check if sent date is a working day by comparing with org holidays
  public static boolean checkifWorkDay(Date sentDate,List<Holiday> holidays){
    
                Date weekStart  = sentDate.toStartofWeek();
                
                for(Holiday hday:holidays){
                        if(sentDate.daysBetween(hday.ActivityDate) == 0)                        
                        return false;                        
                }
                
                if(weekStart.daysBetween(sentDate) ==0 || weekStart.daysBetween(sentDate) == 6)
                {
                       return false;
                } else 
                       return true;
    }

Add these methods in your apex class. lets say name of the apex class > Your_APEX_Class_Name

In order to get 10th business day from today call this method as follows:

date nday = Your_APEX_Class_Name.calculateNthWorkingDay(system.today(),10 );
system.debug('nday is**'+nday);

Hope you will find this code useful.

Thanks,
Rahul G

Tuesday, January 22, 2013

Build a dynamic SOQL query string

This post is one of my promises to myself this year to build reusable components. I will try to post a few here. But whenever i write a code, Good design pattern is to make it as reusable as possible.

This Apex method basically returns the dynamic soql query string when you feed the list of field api names, object name , conditions and limit .
[Edit] This works only for soql and does not do aggregate functions or polymorphic soql or sosl

/* Return dynamic soql query string
     Inputs list of field api names
     Object name
     list of Condition strings eg 'name=\'test\'' , 'noofemployees=0'
     limit string eg '50000'*/
     */ ----------------------------------------------------
     usage
     list<string> fieldname = new list<string>();
     fieldname.add('id');
     fieldname.add('name');
     list<string> conditions = new list<string>();
     conditions.add('name=\'test\'');
   
     eg1:dynamicSoqlString(fieldname,'account',null,null)
     eg2:dynamicSoqlString(fieldname,'account',null,'2')  
     eg3:dynamicSoqlString(fieldname,'account',conditions,'2');
     */
     

     public static string dynamicSoqlString(List<string> apiNames,string objectname, list<string> conditions, string limitcount){
        if(objectname == null || apinames.size()==0){
            return null;
        }
        string soqlstring ='select ';
        for(integer counter =0;counter<apinames.size();counter++){
            if(counter!=0){
                soqlstring+=',';
            }
            soqlstring+=apinames[counter];
        }
        soqlstring += ' from '+ objectname;
        if(conditions != null && !conditions.isempty()){
            soqlstring+=' where ';
            for(integer counter =0;counter<conditions.size();counter++){
                if(counter!=0){
                    soqlstring+=' and ';
                }
                soqlstring+=conditions[counter];
            }
        }
        if(limitcount != null && limitcount !=''){
            soqlstring+=' limit '+limitcount;
        }
        return soqlstring;
    }

Saturday, April 7, 2012

Query User access Level in Apex

     With API 24 salesforce has given access to UserRecordAccess table. This gives us more power in querying whether user have access and upto what level so that we can build our VF and apex accordingly.
http://www.salesforce.com/us/developer/docs/api/index_Left.htm#StartTopic=Content/sforce_api_objects_userrecordaccess.htm

I was writing a VF page in which i needed to have a table of sobject records with Edit and del links for each line item. I was using{!URL for} function which would take care of the link automatically. It would even prevent users who do not have permission to edit or delete the record to take it to the page 'you do not have sufficient permission'.

 I thought it would be nice to know if the loggedin user or profile permission can be queried based on which i could display or hide these links instead of user clicking the link and finding out. Thats when i searched i figured it could be handled with Api 24.0

SELECT RecordId, HasReadAccess, HasTransferAccess, MaxAccessLevel
     FROM UserRecordAccess
     WHERE UserId = [single ID]
     AND RecordId = [single ID]      //or Record IN [list of IDs]

so i needed to get info on hasEditAccess and hasDeleteAccess for loggedin user and based on which i displayed or hid the link. It worked like charm.

Wednesday, March 28, 2012

Sort an Apex class Object List

[Edit : Now there is an interface natively provided by salesforce to sort the class object lists]

I recently needed to sort an apex class object List which was retrieved through a webservice callout as it could not be sorted at the service end.

This is the apex method which was used to build it

 public void testsort(){
        map<string,List<accClass>> stracc = new map<string,list<accClass>>();
        for(accClass a:accClassobj ){
            if(stracc.containsKey(a.name))
                stracc.get(a.name).add(a);           
            else
              stracc.put(a.name,new accclass[]{a});          
        }
        accclassobj= new list<accclass>();
        list<string> nameList = new list<string>();
        nameList.addAll(stracc.keyset());
        nameList.sort();       
        for(string s:nameList){
           accclassobj.addAll(stracc.get(s));          
        }

Steps involved in sorting

1. build a map with object parameter as the key by which we gonna sort and List<object> as the value.
2. sort the keyset
3. arrange the values based on the sorted keyset, so that object gets sorted by that parameter

It is a map of parameter and list of object but not parameter and just object to handle the records which will have same parameters. This sorting handles null values automatically. This sorting can never be dynamic and you will need to create more methods based on the object parameter by which sorting is needed.

Wednesday, January 25, 2012

Identifying SobjectType Dyanamically

getKeyPrefix of Schema.getGlobalDescribe can be used to identify dynamically the SobjectType in Apex.

String prefix = recordId.substring(0,3);
String objectType;
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
for(Schema.SObjectType s : gd.values()){
    if(prefix == s.getDescribe().getKeyPrefix()){
        objectType = s.getDescribe().Name;
    }
}

recordId consists the Id of the sobject Record for whose SobjectType needs to be identified. Above piece of code does it well.