Thursday, 9 January 2014

Convert existing contact to person account???

we just enabled person account on the contact object, but there are lots of existing contacts do not have any 1 to 1 person account on account object.
So use this code to create person accounts for these existing contact without deleting these contacts, as these contacts were referenced by different objects;

//get the business account record type
RecordType NotPersonAccountRecordType = [select Id, Name, SobjectType,
         IsPersonType from RecordType where SobjectType='Account'
         and IsPersonType=False];

// get 1 existing account
Contact c = [select id, AccountId, FirstName, LastName from Contact where IsPersonAccount = false Limit 1];

// create a new account and set the record type to business account
Account newAccount = new Account();
newAccount.Name='' + c.LastName;
newAccount.RecordTypeId = NotPersonAccountRecordType.Id;
insert newAccount;

//get the person account record type
recordType personaccountrecordtype = [select Id, Name, SobjectType,
         IsPersonType from RecordType where SobjectType='Account'
         and IsPersonType=True];

// update the existing contact's account to new account
c.AccountId = newAccount.Id;
update c;

// now get it again and update the firstname and lastname, change the record type to person account
newAccount = [select id,lastName, Firstname, RecordTypeId from Account where Id =: newAccount.Id];
newAccount.RecordTypeId = personaccountrecordtype.Id;
update newAccount;



(OR)


RecordType personaccountrecordtype = [select Id, Name, SobjectType,IsPersonType from RecordType where SobjectType='Account' and IsPersonType=True];
Contact c = [select id, AccountId, FirstName, LastName,Birthdate,Phone from Contact where IsPersonAccount = false limit 1];
               
Account newPersonAccount = new Account();
newPersonAccount.Name=(c.FirstName+c.LastName);
newPersonAccount.Phone=c.phone;

insert newPersonAccount;
 

c.AccountId=newPersonAccount.Id;
update c;
 

newPersonAccount=[select id,lastName, Firstname, RecordTypeId from Account where Id =:newPersonAccount.Id];               
newPersonAccount.RecordTypeId=personaccountrecordtype.Id;

update newPersonAccount;

 

Conversion between Person Accounts and Business Accounts

Selling Business to Business

Salesforce.com was designed mainly for the business to business sales model. Their architecture supports this beautifully. Accounts are companies that you work with. Contacts are the people at those companies that you work with. This design is a huge improvement over contact centric databases like Outlook where you may have the same business noted in your database against several different contacts, but in each case spelled slightly differently (like Snapptraffic, Snapptraffic Consulting, Snapptraffic.com, etc)



This architecture presents a challenge however to the business that sells directly to consumers. There is no need for an Account record in this situation. While that consumer might be associated with a company (where they are employed), the business has no need in most cases to track those details and isn't selling to that person's place of employment. I've seen businesses try to adapt the salesforce account/contact architecture to that business to consumer reality in many different ways, but none of them are all that great.

Selling Business to Consumer - Person Accounts

So Salesforce.com decided quite a few years ago to offer a modification to their out-of-the-box architecture that deals with this challenge. It is called Person Accounts. Person Accounts are only available in Enterprise Edition and are only available by request. A Salesforce.com support representative will actually have to enable this in your system by making a permanent modification (that's right - once enabled, they can't be disabled). 

Person Accounts are really just an Account Record Type. They are a hybrid between accounts and contacts where a contact record is "jammed into" the account. They are tied together, so to speak, so that only one contact exists at the account. The resulting record is both an account with all of it's fields and a contact with all of its fields. When doing a lookup from other objects to a person account, if the object has a lookup to a contact record, then the object can lookup to the Person Account. Likewise, if the lookup is to an account, the object can lookup to the Person Account as well.



This structure now provides a user with the means to say that "Billy Bob Smith" is my client. The fact that Billy Bob works at Acme is irrelevant and no longer needs to be entered.

Working with Both Business and Person Accounts

It is a great solution and works very in almost all situations. Some companies work with both businesses and consumers though. Say, for example, a company that paints buildings. Sometimes they'll be selling to an individual home owner, in which case a Person Account would work best. Other times they'll be selling to a business, like a law office, in which case a Business Account would be used. Salesforce supports this, you just create a Business Account when that is required and a Person Account when that is required.

But what happens if you created a Person Account and later realized that you needed a Business Account? Many times a prospect will contact you and you don't realize until later in the process that you're working with a business. 

Conversion Between these Architectures

Due to the fact that these structures are so different between salesforce.com person accounts and salesforce business accounts, salesforce doesn't provide a way to convert between them. They probably could have provided this functionality, but it would have been difficult to deal with custom objects that may be associated with the contact or the account. The lack of this feature has presented problems to many of my clients over the years.

Custom Development To the Rescue

To handle this limitation we normally put a button on the Person Account page layout for "Convert to Business Account" and on the Business Account Layout for "Convert to Person Account". Then these buttons will call visualforce code that does the appropriate conversion.

The conversion process will literally create a new record of the requested type, then re-associate all child objects/records from the originating account type to the new account type. Then finally, the code will delete the originating record.

This conversion has to be custom to handle your specific customizations. For example, maybe you have 3 Business Account Record Types and 2 Person Account Record Types. In a situation like this, you'll need the visualforce page to ask the user which record type they'd like to convert to. Additionally, if there are custom objects, the conversion has to be written with these particular custom objects in mind.

Wednesday, 8 January 2014

How to use Salesforce workflow rules

This blog provides some examples on when and how to use workflow rules.
Consider the workflow rule as the main container which defines when the workflow should be triggered and what actions should be taken based on the rule criteria.
So when will a workflow be triggered? Salesforce has 3 evaluation conditions:
  1. When a record is created, or when a record is edited and did not previously meet the rule criteria
    In short, this workflow rule will always be triggered (to check if the criteria are met) whenever the record is saved until the criteria are met.
  2. Only when a record is createdIt will only evaluate the criteria when the particular record is created
  3. Every time a record is created or editedIt will always evaluate the criteria every time the record is saved
When all rules are met, the workflow would either execute the workflow actions immediately or place the actions in a queue so that it will be executed when the Time-dependant Workflow Actions condition is met.

Note:
Time-dependant Workflow Actions is not available if the Every time a record is created or edited evaluation option is chosen.

The Workflow Actions

When a workflow rule is triggered and the criteria are met, a specific type of action will be performed or executed within Salesforce.

Some business scenarios and the suggested workflow evaluation rule

Scenario #1:-
The Sales director would like to receive notification for every newly created Closed Won Opportunity in Salesforce

ImplementationOnly when a record is created
This implementation ensures that the workflow rule is only triggered when the Opportunity is created. And if the Opportunity is Closed Won upon creation, the Sales Director would only receive the alert once instead of receiving duplicate emails.
Scenario #2:-

The Account Owner would like to receive notification whenever the Opportunity Owner is changed.
ImplementationEvery time a record is created or edited
The workflow rule will be triggered whenever the Opportunity record is saved and an email alert will be sent to the Account’s Owner whenever the Opportunity Owner is changed.
Scenario #3:-

The record owner needs an indication on when he can send out Invoice when the Opportunity is in Closed Won stage.
Suggested Evaluation CriteriaWhen a record is created, or when a record is edited and did not previously meet the rule criteria
This implementation ensures that only one task is created at the point where the Opportunity is Closed Won and it will not continuously create tasks whenever the Closed Won record is saved.
Scenario #4:-

The Sales Director wants visibility to any tasks there were not executed in Scenario #3. If the task is not executed within 3 days, the Sales Director needs an indication to follow up with the Record Owner.
ImplementationTime-dependant Workflow Action
This implementation ensures that the Sales Director has a scheduled reminder to follow up with the Opportunity Owner. The scheduled reminder will be executed when the Record Owner has yet to complete the given task within 3 days after the task is assigned.

Thursday, 2 January 2014

Concept of Salesforce Trigger

A Salesforce  trigger is  Apex code that executes when we do some DML operation in salesforce object.
In order to execution of trigger it is broadly  of two types ,After Trigger and Before Trigger.


Basic syntax of trigger:-

trigger triggerName on ObjectName (trigger_events) {
    //code_block
}
trigger TestTrigger on Case (Before Insert,After Insert,Before Update ,After Update ,Before Delete ,After Delete,After Undelete) {
 //Code Block
}

[Note:-Keep in mind that only the trigger of that particular object will invoke in which object we will do DML operation, not like  you will insert a record in child object and the trigger in parent object will invoke . It is possible to do some some data manipulation in different object but any way the trigger invoke only the object in which we will do Dml operation].

We can declare more than one trigger event in one trigger ,but each should be separated by comma.
Below are the possible event for trigger.

 >>Before Insert
>>Before Update
>> Before Delete
 >>After Insert
 >>After Update
 >>After Delete
>> After Undelete

There is a System defind class called Trigger which contains 12(twelve) implicit variable,which we can access at run time.
Below are the varibales with description.

1.isExecuting-It rutuns ture if the any code inside trigger context is executing.That means you can test whether your trigger is excuting or not by the help of this variable.

2.isBefore-It rutuns ture if the any code inside trigger context is executing before record is saved to the database.

3.isAfter-It rutuns ture if the any code inside trigger context is executing after record is saved to the database.

4.isInsert-It rutuns ture if the any code inside trigger context is executing due to an insert operation.

5.isUpdate-It rutuns ture if the any code inside trigger context is executing due to an update operation.

6.isDelete-It rutuns ture if the any code inside trigger context is executing due to a delete operation.

7.isUnDelete-It rutuns ture if the any code inside trigger context is executing due to undelete operation  i,e when we recovered data from recyclebin .

8.new-It returns the new version of the object record.

9.newMap-It returns a map  which contains an IDs  as a key and  the old versions of the sObject records as value.This map is only available in before update, after insert, and after
update triggers.

10.old-It returns the old version of the object record.

11.oldMap-It returns a map  which contains an IDs  as a key and  the new versions of the sObject records as value.This map is available for only update and delete trigger.

12.size- It return the size of the trigger.It will return one if you will insert one record, It will return the size of the record you are inserting ,updating or deleting or undeleting.

Examples to test the implicit variable:


trigger  TestTrigger on Case (Before Insert,After Insert,Before Update ,After Update ,Before Delete ,After Delete,After Undelete) {
    System.debug('*********testExecution*************'+Trigger.isExecuting);
    System.debug('****************size of trigger***************'+Trigger.size);
    if(Trigger.isBefore){
        if(Trigger.isInsert){
            for(Case cs:Trigger.new){
                System.debug('********beforeInsertNew************'+Trigger.new);
              
            }
        }
        if(Trigger.isUpdate){
            for(Case cs:Trigger.new){
                System.debug('********beforeUpdateNew************'+Trigger.new);
                System.debug('**********beforeUpdateOld**********'+Trigger.old);
                System.debug('********beforeMapUpdateNewMap************'+Trigger.newMap);
                System.debug('**********beforeMapUpdateOldMap**********'+Trigger.oldMap);
            }
      
        }
        if(Trigger.isDelete){
            for(Case cs:Trigger.old){
              
                System.debug('**********beforeDeleteOld**********'+Trigger.old);
                System.debug('**********beforeMapDeleteOldMap**********'+Trigger.oldMap);
            }
      
        }
  
      
    }
    if(Trigger.isAfter){
        if(Trigger.isInsert){
             for(Case cs:Trigger.new){
                System.debug('**********afterInsertNew**********'+Trigger.new);
                System.debug('**********afterInsertNewMap**********'+Trigger.newMap);
             }
         }
        if(Trigger.isUpdate){
             for(Case cs:Trigger.new){
                System.debug('**********afterUpdateNew**********'+Trigger.new);
                System.debug('*************afterUpdateOld*******'+Trigger.Old);
                System.debug('**********afterUpdateNewMap**********'+Trigger.newMap);
                System.debug('*************afterUpdateOldMap*******'+Trigger.oldMap);
            }
        }
       if(Trigger.isDelete){
            for(Case cs:Trigger.old){
                System.debug('*************afterDeleteold*******'+Trigger.Old);
                System.debug('*************afterDeleteoldMap*******'+Trigger.oldMap);
            }
       }
       if(Trigger.isUnDelete){
            for(Case cs:Trigger.new){
                System.debug('**********afterunUndeleteNew**********'+Trigger.new);
                System.debug('**********afterunUndeleteNewMap**********'+Trigger.newMap);
              
           }
       }
    }
}
[Note: Just copy this code and paste in case object or else in which object you want to test just the object name in the above example.After saving the trigger you can insert ,update ,delete and undelete records and just create debug log for different situation and observe.]

Below is the steps how to add this trigger in sales force in case object.

click Your Name  Setup  Cases  Case   Triggers  New

Just remove the existing code and paste the above code ans save the code .


After that follow the below steps to create the debug log.

click Your Name  Setup  Monitoring Debug logs  

Click on New button to set the debug log in your name .

Now you can create record for case object and try to observe the debug log and just realize all context variable.
Just Insert ,update delete and undelete one record from recycle bin.