Tuesday, 27 October 2015

Considerations for Approval Process: Field updates don’t evaluate custom validation rules on fields


Requirement
I came across one scenario where the requirement was to prevent an approval process field update action when a Credit/Debit record is in Invoiced status though the record is still in the approval process.

Background
When a Credit/Debit record is submitted for approval process, there may be scenario where the approver may be on leave or may delay in approving that request. In the meantime, SAP, an external integrated system, can make an update on this record by invoicing the data even without any approval notification from Salesforce.com to SAP.

Actions taken
I thought of keeping a validation rule to prevent the approver from making any change if the record is invoiced from SAP.
However this didn't happen because of this simple fact below.

Facts
One of the considerations for Approval Process is "Field updates don’t evaluate custom validation rules on fields". So in this case, a custom validation rule won’t fire inside an approval process.

To be continued..
The search for some other workaround is ON..  

Friday, 16 October 2015

Scheduling Batch Job To Run Every N-Minutes in Salesforce.com


Have you ever wondered or come across scheduling batch job to run every N-Minutes( for example 1 minute or 5 minutes)?
Yes, I have! Since this is not possible to do thru standard Salesforce UI.

Sometimes  in order to do so, we go for scheduling multiple times; for example 11 times if it has to be scheduled every 5 minutes. Here is the next question: Can't it be done in a single scheduling attempt? Yes, it can be. The next is the solution..  


So here is a small code to do so for every 5 minutes. You can customize your logic for every N_minutes. You can execute this piece of code in developer console as well.

DateTime myDateTime = System.Now() ;
System.debug('Sudhir myDateTime:: ' + myDateTime) ;


static Integer iHour = myDateTime.hour() ;

System.debug('Sudhir iHour :: ' + iHour) ;

static Integer iMinute = myDateTime.minute() ;
System.debug('Sudhir iMinute:: ' + iMinute) ;

static Integer iSecond = myDateTime.second() ;
System.debug('Sudhir iSecond:: ' + iSecond) ;

for(Integer i = 0; i < 60 ; i = i + N){ 
    if(iSecond > 59){
        iSecond = 0 ;
    }  
  if(iMinute > 55){
        iMinute = 0 ;
        iHour = iHour + 1 ;
    } else{
        iMinute = iMinute + N ;
    }
    String sExpression = String.valueOf(iSecond) + ' ' + String.valueOf(iMinute) + ' ' + '*' +  ' ' + '*' + ' ' + '*' + ' ' + '?' + ' ' + '*' ;
    System.debug('Sudhir sExpression:: ' + sExpression) ;

     ScheduledBatchJob_APIName oScheduledBatchJob_APIName = new ScheduledBatchJob_APIName () ;
     System.schedule('Comment for Scheduled batch Job' + '-' + i, xpression, oScheduledBatchJob_APIName) ;
}








Happy Apex coding and sharing.. 

Monday, 3 August 2015

SFDC-SAP Integration: Project delivered, Lessons learnd

Delivering SFDC-SAP Integration Project involving 7 different interfaces to one of our US clients is really a milestone in one's career.

I believe that this single blog is not sufficient to unravel my journey to this strategic project, nevertheless, I would like to highlight some of the things I learnt during this period. Before I begin, I would like to take a moment to appreciate some of the magnificent people I met on this journey and who helped me to move ahead and succeed.
Thank you so much to my colleagues with whom I learnt things to manage and take more responsibility   

Let me start from the end, the last few days.. as I feel that the ends are just the beginnings of new possibilities, thoughts, and opportunities.

Last month before Go-Live was like a nightmare (with a positive outcome); groups of hard core developers, analysts and experts working so hard to deliver this strategic project on July 25, 2015.

A personal opinion - Many software engineers develop and even deliver the project they have been working upon; after that they either leave that project and move on to other project or hand over to the other support team.

However my opinion is sightly different. I prefer to adhere to those projects for sometime after Go-Live and then feel/analyze how end users are using or how the business solution is performing. I would prefer to jot down some of the information/knowledge I learnt/gained during the last few moments of the project delivery. The points down below are ad hoc points coming into my mind while writing, it may not seem in sequence, however all points are important.  




1. Capture Request-Response payload in the Integration Logger object, not just success or response message. Why so because you will not have to go to the external system team to ask to push the data again or to ask for xml payload during analysis.

2. Returning only one response message, not one message per wrapper object, corresponding to one request containing multiple wrapper object information.

3. Returning exact error message to external system, not some hard coded message. It will help analyze the data and prevent such errors happening again and again.

4. To re-trigger the interface again for the failed records, make it possible for end users to trigger it. They should not raise a ticket to get it done from the admin team. Make some UI which they can use to feed in the failed record id and then click on button to send the payload to external system.

5. Use collections like lists, sets and maps efficiently so as to prevent various limits like SOQL limit and also keep in mind to check the null or empty conditions.

6. If there are various other old system connected to the SFDC system, analyze if the new integration has any impact and then document all potential impacts and effective solutions.


7. Follow the post Go Live hyper-care support process so that everything issue can be tracked and keep into everyone's notice. It will make you responsible and you will not face any accountability if something bad comes up and if it was not brought into notice previously.

8. Plan your Go-Live deployment management and coordination between onshore and offshore teams. Living in two different time zone helps a lot. It facilitates 24x7 execution flow. Keep all Profile level securities documented. Divide all tasks into Pre, during and post deployment plans.
Prepare couple of deployment drills, Microsoft project plan,

9. Keep some reports ready for tracking the transaction(success / failed) between the two system.

10. Test the updated system with various profiles from various regions so that if this project is only applicable for a given region, it should not impact the other region business process.

11. In the mean time, keep care of your health. Exercise, Yoga daily to keep your mind analytical and active. The last week of deployment will definitely be like an ordeal. But believe me after you come across this period, you will be proud of yourself to witness positive vibes inside you.


12. Keep your offshore team informed about the current changes by giving quick updates mail. Track and document What was done today, What will be done tomorrow and What can be passed onto the offshore team. Remember it's not all about how independent you work but also how collaborating you are and how efficiently you can use the available resources.


13. Perform some analysis on the existing reports for the objects you are modifying/touching as a part of this integration. There may be scenario where you try to convert relationship between two objects from master detail to lookup. It may impact your reports as the Standard Report Types available due to Master Detail relationship will no longer be available. And also keep in mind if you are deleting some fields which are referenced in the reports,  your report may fail.


14. More importantly, keep yourself aware of other external system processes, not just your own system. It may help you understand the whole architecture/landscape of the integration and thereby you may be able to develop robust and stable integrated environment.

15. Keep writing your own short notes, blogs or tweets. It will keep your learning alive and at the same time you share this to the Salesforce or knowledge community.

16. If you are stuck somewhere technically or functionally, don't hesitate to reach out to your senior colleagues, old colleagues or even Salesforce Support team. have a holistic discussion and get the right information.

17. During hyper care post Go Live, always keep track of the issues by opening tickets or maintaining excel sheets. Keep daily meetings and analysis.

18. Know you customers, interact with them. It will help you understand their issue clearly, you can reach out to them confidently and you can solve the issues quickly. So basically know your audience and their requirements.












Happy Salesforce.com Implementation and Knowledge Sharing..                                              

The Journey Continues..

Sunday, 5 July 2015

How to deal with: Apex CPU time limit exceeded


In my recent project on SFDC-SAP integration, there is one interface called "Customer Master Data and Hierarchy". SFDC has exposed this service thru SOAP APIs. The web service class is so huge and complex (more than 2000 LoC) that I have to keep the code optimization and performance in mind. During bulk data load testing in UAT, SFDC thows "Apex CPU time limit exceeded" limit exception during run time.

Wayout: Optimize your code by using maps and sets. Use less or avoid using nested For loops as the more is the iterations, the more time it takes for the logic when there are bulk load (thousands and thousands of records).

In my case,

1. there were two nested For loops which was causing the error: Replaced with only one For loop and used maps and sets for compensating this change.
2. the packet size from SAP:  When it was set to 999, SFDC was skipping some intermidiate batch of data. When it is set to 200. everything is perfect.

How to deal with: System.ListException: Duplicate id in List [duplicate]


Sometimes you may have received this error:
System.ListException: Duplicate id in List [duplicate]..

The caveat is: List should not hold multiple instances of the same object. Otherwise you will get this run time exception.

It's better to user set or map as they remove the duplicates.

Account oAccount = new Account(Id = sSfdcAccountId) ;
list<Account> listAccountWithDuplicateIds = new list<Account>() ;
listAccountWithDuplicateIds.add(oAccount) ;
Database.insert(listAccountWithDuplicateIds, false) ;

will result in System.ListException: Duplicate id in List [duplicate]..

As per your needs, use either:

1. map<String, Account> mapAccountId2Account = new map<String, Account>() ;
mapAccountId2Account.add(oAccount .Id, oAccount ) ;
Database.insert(mapAccountId2Account.values(), false) ;

2. setAccount.addAll(listAccountWithDeuplicate) ;

#MySfdcTweets #SalesforceDotCom #SFDC

Saturday, 4 July 2015

HTTPS Security Certificate Change from SHA-1 to SHA-256 hash algorithms


Recently Salesforce upgraded security for HTTPS certificate by replacing SHA-1 signature hash algorithm with SHA-256 signed hash algorithm, and CA signed certificates to be only Symantec-issued certificates.

We were in middle of UAT, and Go-Live planned in couple of weeks ahead. Initially the self signed certificate SAP used was SHA-1 signed. There was one scenario where suddenly the connection between SAP and SFDC in all the sandboxes seemed broken resulting in communication error and failure. The most likely reason, which I later figured out in my opinion, was this HTTPS certificate security upgradation. SAP PI, the middleware, had to re-install this new SHA-256 certificate again and restart its XIAdapter to get the connection working.

The only potential change in our case was the middleware SAP PI to update the cached certificate with this new upgrade.

For more details, refer this SFDC knowledge article





Thursday, 8 January 2015

Is Self Chaining possible in Queueable Interface? - The Climax

Okay! So the story ends like this:

"But currently the chaining feature will be available in the spring 15 release. For the winter 15 release the queueable can call itself only once."

Let me put a period to my tryst with ‪#‎QueueableInterface‬ self-chaining capability till my sandbox is upgraded to Spring '15

Happy Apex coding !

‪#‎MySfdcTweets‬

Wednesday, 7 January 2015

Is Self Chaining possible in Queueable Interface? - Part 2

With reference to previous #MySfdcTweets on #QueueableInterface self-chaining possibility, I encounter this error:

System.AsyncException: Maximum callout depth has been reached.

Salesforce documents says, "Maximum stack depth is two, which means you can add only one job from an executing job", which I think I am abiding by literally.

The reason in my case seems to be this:

I get this AsyncException because of recursive chaining like Job A --> Job A --> Job A.

So let me put this into a better perspective: ;)

Maximum stack depth should mean that there could be maximum two sequential jobs(Job A ---> Job B, not Job A --> Job B --> Job C and so on.) in a Queueable context.

I even tried putting some static flag to prevent recursion so as to maintain stack depth to 2. It too didn't work. :P  It feels that the static variable somehow getting lost in the asynchronous context. :D

However, it should be better to get this understanding verified by SFDC Technical Expert Team.

...To Be Continued  (Y)


My experience(twist and turns) with Queueable Interface implementation reminds me of this beautiful song.  Twist and turns by James Spencer

Listening to and feeling invigorated..

Tuesday, 6 January 2015

Is Self Chaining possible in Queueable Interface?

#QueueableInterface allows Chaining Jobs.

For re-sending the failed records during a web service callout from SFDC to SAP, today I was just wondering if Self-Chaining is possible.

I wrote the below piece of code:

System.enqueueJob(new SameClassImplementingQueueable(listObject)) ;

And it compiled successfully. (Y)

So I believe the compiler allows us to perform self-chaining as well. Now I need to check what happens at the runtime.

The only restriction I see for implementing Queueable Interface is this: "The maximum number of jobs in the chain (maximum stack depth) is two, which means you can add only one job from an executing job".

I believe I am within the Salesforce limits.  :P  ;)

P.S: If it happens, I need to see how it behaves in its Test Class.  :D

#MySfdcTweets  #SalesforceDotCom  #SFDC

Monday, 5 January 2015

Salesforce Spring '15 - Biggest Ideas Release Ever

#Salesforce Spring '15 could be annotated as the #BiggestIdeasReleaseEver.

The Sandbox Preview window for Spring '15 is scheduled to begin on January 9, 2015.


Can't wait more for #ApexFlexQueue (which allows the submission of up to 100 batch jobs and to prioritize the jobs by reordering) and #ProcessBuilder (which extends the capabilities of workflow to a new level).

Coming in the next release - Spring '15

#MySfdcTweets

Saturday, 3 January 2015

A blend of SFDC Automaticity

"For a bidirectional synchronization between SFDC and SAP, Using an amalgamation of Apex Trigger, Queueable Interface, Web Service callout to SAP, AsyncApexJob, Integration Logger, Automated submission to Approval Process and Batch Apex with Schedulable Interface."

WOW !

It seems exciting. Correct?

However, it feels even more interestingly super-thrilling to do it practically.

‪#‎MySfdcTweets‬ ‪#‎Salesforce‬ ‪#‎SFDC‬

Friday, 2 January 2015

Pricing Agreements (Contracts) in Salesforce.com CRM

Pricing, in Salesforce CRM, is one of the most interesting and complex process to set up and to integrate it with SAP.
Going through lots of discussion regarding redesigning the Pricing process in the on-going project and then converting it into the SAP requirements for creating Pricing Agreements in SAP.
Being as one of the sensitive data, Pricing/or Contract calls for an extra attention psychologically.   :P 

Pricing is the Contract Agreement between Customer and the Company. It could include the Reference Prices, Base Prices, Pricing Exceptions, Rebates, Payment Terms, different kinds of Surcharges at various levels for a product being purchased. 

For sending these info to SAP, each pricing record is mapping to corresponding Condition Types and Condition Tables (these are SAP Terminologies) which fetch key fields in SAP to create the corresponding SAP records.

This agreement could be later used to generate Contracts in pdf format using apps like Conga Merge or Thunderhead and then later could be sent for signature using apps like Docusign.

I hope I explained succinctly.    ;)

Queueable Interface: First time hands on

Recently implemented "Queueable Interface" for asynchronous processing of bulk records for making a web service callout from Salesforce.com to SAP system. 

A better enhanced feature of Salesforce.com as compared to the previous one; @future annotation. :) 

It's been fun incorporating this into my on-going integration project...... 

Waiting to release my next blog on it. :)

‪#‎MySfdcTweets‬ ‪#‎Salesforce‬ ‪#‎SFDC‬

Wednesday, 23 July 2014

Excerpts from Salesforce Summer of Hacks, Bangalore July 18-20 , 2014

Does ever dream come true? Yes it does, believe me. 
Salesforce1 opens up a gateway to infinite opportunities and innovations.


4 Cities: London, New York, Los Angeles & Bangalore;
$50,000 in Prizes;
12 Winners....

Being one of the winners is really a matter of profound happiness and achievement.
The moment captured @ hackathon for winning 3rd Prize for building "Clients News Tracker" Salesforce1 mobile application.

The selection criteia was based on 4 parameters:
  • Innovation
  • Business Potential
  • User Experience
  • Use of Salesforce platform and mobile technology


Day 1

Every team had to submit their ideas and then vote for others. Top 30 teams getting most number of votes were allowed to move to next round of Salesforce1 mobile app development.
The hackathon team had created one private GitHub repository for committing our projects. The window for committing our projects used to open only once a day. So altogether we had to do 3 commits. Team failing to commit within that time window would be disqualified.

Day 2

Whole day & night [24X7] every team was dedicated to building, analyzing their applications. In between the hackathon team kept on organizing various fun activities to keep the participants active and jovial.

Day 3

The D-day finally had arrived. Every team had to do final commit between 11 PM to 2 PM. After that they had to prepare presentations and rehearse. Because each team had to complete their App Demo within 3 minutes including ppt, app description and demo followed by a 2 minutes questions raised by the judges.
Finally the time had knocked our doors: It was 7 PM and it seemed like a lull before the storm.

Since a video says a thousand words than a sentence.   Here goes that precious moments.. Click to View. and my team with the prize on twitter.


Salesforce Summer of Hacks provided a unique platform for Salesforce1 enthusiasts to showcase their talents and unleash their million dollars ideas. We witnessed lots of cool apps and believed that yes with Salesforce1, mobile apps can be built more quickly and make our customers happy.

Starting my IT career with Salesforce.com CRM in a global organization like Thomson Reuters has always been enriching and learning experience for me.
Participating in various Salesforce meetups, Seminars and other discussions has always helped me expand my sphere of influence and getting continuous accolades from my team and friends has kepy my morale high. I sense the same team here in CSC. 

Looking forward to achieving more milestones and continuing my journey to learning in this new organization as well.
Way to go !

Friday, 18 July 2014

How to hide buttons from apex:detail component?

Background: While working on an app, I came across this scenario I was using <apex:detail  /> component in a Visualforce Page.
Issue: My concern was to remove all those visible button which come alongwith this component usage.

                                                  Initial snapshot


So here is a way to hide those button using CSS:

Solution:

<style type="text/css">
      
        input.btn[name="clone"] {
            display: none;
        }
        input.btn[name="edit"] {
            display: none;
        }
        input.btn[name="del"] {
            display: none;
        }
      
</style>

                                                      After snapshot








Point to be noted: Use "Inspect Element" to find the correct names of the buttons and then use them accordingly in the [name="buttonName"] inside the CSS.
If the name of the buttons change, you have to update them in CSS.

Happy Apex Coding..