Ads

Thursday 22 August 2013

How to calculate date for weekday and weekend only In Salesforce?

In Salesforce, it is easy to calculate number of day between 2 date.
Just create a formula field, example: End_Date__c - Start_Date__c. DONE!!!

But, is it possible to find out only weekday and only weekend between 2 date?
Hmmm.... most of us will think about Apex Trigger.
Yes, it is correct solution, apex trigger able to calculate without issue, but, if you are not from developer, you need a developer for this.

Wait a minute.... Can we use 'just' formula to calculate weekday and weekend?

YES, it is possible with complex formula. Here we go:

To calculate Weekday
CASE(MOD( Request_Date__c - DATE(2007,1,1),7),
0 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,2,2,3,3,4,4,5,5,5,6,5,1),
1 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,2,2,3,3,4,4,4,5,4,6,5,1),
2 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,2,2,3,3,3,4,3,5,4,6,5,1),
3 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,2,2,2,3,2,4,3,5,4,6,5,1),
4 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,1,2,1,3,2,4,3,5,4,6,5,1),
5 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,0,2,1,3,2,4,3,5,4,6,5,0),
6 , CASE( MOD( Execution_Date__c - Request_Date__c ,7),1,1,2,2,3,3,4,4,5,5,6,5,0),
999)
+ (FLOOR(( Execution_Date__c - Request_Date__c )/7)*5)
-1

To calculate Weekend
CASE(MOD( Request_Date__c - DATE(2007,1,1),7),
0 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),1,0,2,0,3,0,4,0,5,1,6,2,0),
1 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),0,0,1,0,2,0,3,0,4,0,5,2,2),
2 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),0,0,1,0,2,0,3,1,2),
3 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),0,0,1,0,2,1,2),
4 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),0,0,1,1,2),
5 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),0,1,2),
6 , CASE( MOD( Execution_Date__c - Request_Date__c, 7),6,2,1),
999)
+ (FLOOR(( Execution_Date__c - Request_Date__c )/7)*2)

If you see in formula above, we have DATE(2007,1,1), this is refer to 1-Jan-2007 is Monday. So, you can use any date which is Monday, example 1-Jan-1900

How to undelete records in Salesforce?

Salesforce keep record you delete to Recycle Bin for 15 days with maximum record of 25 times the Megabytes (MBs) in your storage. For example, if your organization has 1 GB of storage then your limit is 25 times 1000 MB or 25,000 records. If your organization reaches its Recycle Bin limit, Salesforce automatically removes the oldest records if they have been in the Recycle Bin for at least two hours.

You can manually undelete records by click Recycle Bin icon in bottom left menu. Undelete account will include contact, case, opportunity tagged to that Account. But, if you have many records or you have specific record Id or you want to undelete records with some conditions, manually delete is not an option, use Apex code for it.

You not really need to be good developer to utilize Apex code. Here we go:

1. Open Developer Console
From your name in top right, look for Developer Console











2.From Developer Console
Go to Debug menu and select Open Execute Anonymous Window











3. Enter SOQL 
Example:
Account[] a = [SELECT Id FROM Account WHERE name = 'singtel' ALL ROWS];
undelete a;
Important to add ALL ROWS, otherwise deleted records will be not return on query.






4. Monitor Apex Debug Log
Go to Monitor - Logs - Debug Logs (in Salesforce menu, not Developer console)
Add user to monitor, default it will capture 20 log request for the users

5. Execute 
Click Execute button in Enter Apex Code window

6. Back to Debug Log
Select latest debug log and click View to monitor

ISBLANK() or ISNULL() in Salesforce?

To determine if an expression has a value or not, you can use ISBLANK() function in Salesforce. It will  returns TRUE if it does not and if it contains a value, this function returns FALSE. You can use this function in formula field, as well as in workflow.

ISBLANK(expression) and replace expression with the expression you want evaluated.
sample:
IF(ISBLANK(Maint_Amount__c), 0, 1)

A field is not empty if it contains a character, blank space, or zero. For example, a field that contains a space inserted with the spacebar is not empty.

If you use this function with a numeric field, the function only returns the specified string if the field does not have a value and is not configured to treat blank fields as zeroes.

You also can use BLANKVALUE() function to determine if an expression has a value and returns a substitute expression if it does not. If the expression has a value, returns the value of the expression.
sample:
BLANKVALUE(Payment_Due_Date__c, StartDate +5)
Use the same data type for both the expression and substitute_expression.

How about ISNULL() ?
Use ISBLANK instead of ISNULL in new formulas. ISBLANK has the same functionality as ISNULL, but also supports text fields. Salesforce will continue to support ISNULL, so you do not need to change any existing formulas.

The same goes for NULLVALUE(), it is similar with BLANKVALUE(), with exception:

Avoid using NULLVALUE with text fields because they are never null even when they are blank. Instead, use the BLANKVALUE function to determine if a text field is blank.
Don’t use NULLVALUE for date/time fields.

Choose Treat blank fields as blanks for your formula when referencing a number, percent, or currency field. Choosing Treat blank fields as zeroes gives blank fields the value of zero so none of them will be null.

Wednesday 21 August 2013

How to Customize the Lead Conversion Process in Salesforce.com?

trigger lead_onConvert on Lead (after update) {

/*  Create variables to store the lead values,new and old.  This will be used below to determine if the leads are being converted,  not converted yet, or has already been converted.*/

List<Lead> newLeads = trigger.new;
Map<Id, Lead> mOldLeads = trigger.oldMap;
Lead oldLead;

/* Create sets of Ids to store the records associated with the converted leads */

Set<Id> convertedAccountIds = new Set<Id>();
Set<Id> convertedContactIds = new Set<Id>();
Set<Id> convertedOpportunityIds = new Set<Id>();

/* Loop through the leads submitted through this trigger.  Populate the appropriate sets of Ids for each lead with populated values.*/

for (Lead l : newLeads) {

if (l.convertedAccountId != null) {
convertedAccountIds.add(l.convertedAccountId);
}

if (l.convertedContactId != null) {
convertedContactIds.add(l.convertedContactId);
}

if (l.convertedOpportunityId != null) {
convertedOpportunityIds.add(l.convertedOpportunityId);
}
}

/* Extract the records associated with each set of Ids populated above.  Once the data has been extracted store it in a map so it can efficiently be referenced
 in the main loop below.*/

List<Account> accounts =[SELECT Id, Name FROM Account WHERE Id IN : convertedAccountIds];

Map<Id, Account> mAccounts = new Map<Id, Account>(accounts);

List<Contact> contacts =[SELECT Id, Name FROM Contact WHERE Id IN : convertedContactIds];

Map<Id, Contact> mContacts = new Map<Id, Contact>(contacts);

List<Opportunity> opportunities =[SELECT Id, Name FROM Opportunity WHERE Id IN : convertedOpportunityIds];

Map<Id, Opportunity> mOpportunities = new Map<Id, Opportunity>(opportunities);

/* Create lists of records to be updated in bulk at the end of this trigger.  We use a separate list to ensure we aren't updating records that are  not affected by this trigger. */

List<Account> updateAccounts = new List<Account>();
List<Contact> updateContacts = new List<Contact>();
List<Opportunity> updateOpportunities = new List<Opportunity>();

/*
* MAIN LOOP
*
* Loop through all leads submitted through this trigger.
* If this trigger was executed because of a conversion
* we will populate the related records.
*/
for (Lead newLead : newLeads) {

// Get a reference to the old values associated
// with this lead.
oldLead = mOldLeads.get(newLead.Id);

// Determine if the lead was converted or not.
// If the previous status was not converted and
// the current status is converted, then this
// trigger executed because of a conversion.
if (!oldLead.IsConverted && newLead.isConverted) {

// ** CONVERSION FOUND **

Account account = mAccounts.get(newLead.convertedAccountId);
// Make appropriate updates here.
updateAccounts.add(account);

Contact contact = mContacts.get(newLead.convertedContactId);
// Make appropriate updates here.
updateContacts.add(contact);

Opportunity opportunity = mOpportunities.get(newLead.convertedOpportunityId);
// Make appropriate updates here.
updateOpportunities.add(opportunity);

}
}

/* Update the records for any update list  populated with records.*/

if (updateAccounts.size() > 0) {
update updateAccounts;
}

if (updateContacts.size() > 0) {
update updateContacts;
}

if (updateOpportunities.size() > 0) {
update updateOpportunities;
}
}

How We can get the list of contacts and accounts converted from leads on a particular Date?

We can get the list of contacts and accounts converted from leads on a particular Date

Actually everyone thinks it's impossible to find Solution,But after a lot of research I found a way for this:

Run a Report on Account History/ Contact History with a Specified date and Add the Filter Field/Event set to Created by Lead Covert to find the records that were created upon lead conversion, or set to Lead Converted to Contact to find the records that already exist and merged with lead conversion.




Tuesday 20 August 2013

Phone Number validation In Salesforce?

Converting 10-Lines of Apex code to a 1-line Validation Rule Formula
Code clean-up is what I'm doing these days ... lots of code clean-up. One of our Salesforce.com orgs (we have sixteen of them) currently has 72% test coverage in production. I'm not sure how the previous administrators were able to install code below the 75% threshold, but they managed. I'm tasked with getting that code cleaned up, so I can deploy a new release.

While looking for areas to improve code coverage, I stumbled upon this trigger:

trigger checkAccountPhoneNumberBiBu on Account (before insert, before update) {
   for (Account account : Trigger.new) {
      if (account.Phone==null) continue;
      Pattern p = Pattern.compile('[-() ]');
      String sPhone = p.matcher(account.Phone).replaceAll('');
      // check length without punctuation
      if (sPhone.length() != 10) account.Phone.addError(' Phone number must have 3 digit area code and 7 digit number');
      p = Pattern.compile('\\d');
      sPhone = p.matcher(sPhone).replaceAll('');
      if (sPhone.length() > 0) account.Phone.addError('Phone number must be formatted as (999)999-9999');
   }
}

This trigger looks at the value entered in the "Phone" field before an Account record is inserted or updated; if the phone field is not in the (999)999-9999 format, it errors out and notifies the user to enter the phone # in the proper format.

In addition to this Apex code, the developer also had to write a testmethod to ensure coverage of the trigger. His code was only getting 67% test coverage (which is what brought the trigger to my attention in the first place).

As I started looking at what I needed to add to the testmethod to ensure 100% coverage, I realized it would be easier to just get rid of the trigger altogether, and replace it with a Validation Rule. That 10 lines of Apex code was reduced to a 1-line formula in a validation rule:

NOT(REGEX(Phone, "\\D*?(\\d\\D*?){10}"))

Standard profiles in Salesforce?


Standard profiles cannot be deleted and permissions cannot be edited.