Create PriceBook || Product || PricebookEntry || OpportunityLineItem(Opportunity Product)

When we create an Opportunity Line Item we basically link PricebookEntry record and Opportunity Record by creating a junction names OpportunityLineItem.So every time if we want to update unitprice(salesprice) price for OLI we need to update pricebook entry record since unit price is of Pricebook entry field and Total price is of OLI field.

1.Create a PriceBook
pricebook2 pb=new pricebook2();
pd.name='MyPriceBook';
pb.isActive=true;
insert pb;
2.Create a Product
Product2 prod = new Product2();
prod.Name = 'MyProduct';
prod.ProductCode = 'MyProduct';
prod.isActive = true;
insert prod;
3.Add(Link) a product to Pricebook
PricebookEntry pbEntry = new PricebookEntry();
pbEntry.Pricebook2Id = pricebookId;
pbEntry.Product2Id = prod.Id;
pbEntry.UnitPrice = 100.00;
pbEntry.IsActive = true;
insert pbEntry;
4.Create(Add) Opportunity Line Item(Opportunity Product).This assumes  already have an opportunity created
OpportunityLineItem oli = new OpportunityLineItem(
OpportunityId = opp.Id;
Quantity = 5;
PricebookEntryId = pbEntry.Id;
TotalPrice =123;
insert oli;

Passing Objects to Future Annotated Methods

One of the restrictions of future annotations is that you can not pass sObjects or objects as arguments to the annotated method.

public class clsForAllFutureMethods
{
  @future
  public static void FirstFutureMethod(List<String> lst)
  {
  }

}

But there is a way we can pass using  JSON serialize|deserialize methods.

public class wrapperClass{

 public Contact objContact{set; get;}
 public String AccountName{set; get;}
 public String OpportunityName{set; get;}
 

    public wrapperClass(Contact con, String aName, String oName) {
     objContact= con;
     aName = AccountName;
     oName= OpportunityName;
    }
}

---------------------------------------------------------------------------
List<String> lstString= new List<String>();
wrapperClass objWrap1= new wrapperClass(new Contact(LastName='Contact1'), 'Account1', 'Opp 1');
wrapperClass objWrap2= new wrapperClass(new Contact(LastName='Contact2'), 'Account2', 'Opp 2');


//serialize my objects
lstString.add(JSON.serialize(objWrap1));
lstString.add(JSON.serialize(objWrap2));
clsForAllFutureMethods.FirstFutureMethod(lstString);


---------------------------------------------------------------------------
We need to deserialize the JSON string as


public class clsForAllFutureMethods
{
  @future
  public static void FirstFutureMethod(List<String> lst)
  {
   List<wrapperClass> lstWrap=new List<wrapperClass>();
      for (String objWrap: lst)
     {

       lstWrap.add((wrapperClass) JSON.deserialize(ser, wrapperClass.class));
     }

  }
}

sObjects or Objects can’t be passed as an arguments to future methods


The reason why sObjects can’t be passed as arguments to future methods is because the sObject might change between the time you call the method and the time it executes.
 In this case, the future method will get the old sObject values and might overwrite them. 
 To work with sObjects that already exist in the database, pass the sObject ID instead (or collection of IDs) and use the ID to perform a query for the most up-to-date record. 

Lead convert fail when there is a process defined to update the lead during the conversion

If you have a process created for the Lead object in the process builder, you may encounter an error similar to the one below when trying to convert a lead.

"Error: System.DmlException: Update failed. First exception on row 0 with id XXXXXXXXXXXXXXX; first error: CANNOT_EXECUTE_FLOW_TRIGGER, The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID XXXXXXXXXXXXX. Contact your administrator for help.: [] Class.leadconvert.BulkLeadConvert.updateLead: line 1375, column 1 Class.leadconvert.BulkLeadConvert.convertLead: line 151, column 1"

This will happen if the process you have created for leads is trying to update the lead when it's converted. When a lead is converted, some values on the lead are updated automatically and therefore, if the process is set to start "when a record is created or edited" and the criteria on is met, the process will try to update the lead after being converted, which is not possible. 

Converting Leads


The convertLead DML operation converts a lead into an account and contact, as well as (optionally) an opportunity.convertLead is available only as a method on the Database class; it is not available as a DML statement.
Converting leads involves the following basic steps:
  1. Your application determines the IDs of any lead(s) to be converted.
  2. Optionally, your application determines the IDs of any account(s) into which to merge the lead. Your application can use SOQL to search for accounts that match the lead name, as in the following example:
    1SELECT Id, Name FROM Account WHERE Name='CompanyNameOfLeadBeingMerged'
  3. Optionally, your application determines the IDs of the contact or contacts into which to merge the lead. The application can use SOQL to search for contacts that match the lead contact name, as in the following example:
    1SELECT Id, Name FROM Contact WHERE FirstName='FirstName' AND LastName='LastName' AND AccountId = '001...'
  4. Optionally, the application determines whether opportunities should be created from the leads.
  5. The application queries the LeadSource table to obtain all of the possible converted status options (SELECT ... FROM LeadStatus WHERE IsConverted='1'), and then selects a value for the converted status.
  6. The application calls convertLead.
  7. The application iterates through the returned result or results and examines each LeadConvertResult object to determine whether conversion succeeded for each lead.
  8. Optionally, when converting leads owned by a queue, the owner must be specified. This is because accounts and contacts cannot be owned by a queue. Even if you are specifying an existing account or contact, you must still specify an owner.

Example

This example shows how to use the Database.convertLead method to convert a lead. It inserts a new lead, creates a LeadConvert object and sets its status to converted, then passes it to the Database.convertLead method. Finally, it verifies that the conversion was successful.
01Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
02insert myLead;
03
04Database.LeadConvert lc = new database.LeadConvert();
05lc.setLeadId(myLead.id);
06
07LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
08lc.setConvertedStatus(convertStatus.MasterLabel);
09
10Database.LeadConvertResult lcr = Database.convertLead(lc);
11System.assert(lcr.isSuccess());

Convert Leads Considerations

  • Field mappings: The system automatically maps standard lead fields to standard account, contact, and opportunity fields. For custom lead fields, your Salesforce administrator can specify how they map to custom account, contact, and opportunity fields. For more information about field mappings, see the Salesforce online help.
  • Merged fields: If data is merged into existing account and contact objects, only empty fields in the target object are overwritten—existing data (including IDs) are not overwritten. The only exception is if you specifysetOverwriteLeadSource on the LeadConvert object to true, in which case the LeadSource field in the target contact object is overwritten with the contents of the LeadSource field in the source LeadConvert object.
  • Record types: If the organization uses record types, the default record type of the new owner is assigned to records created during lead conversion. The default record type of the user converting the lead determines the lead source values available during conversion. If the desired lead source values are not available, add the values to the default record type of the user converting the lead. For more information about record types, see the Salesforce online help.
  • Picklist values: The system assigns the default picklist values for the account, contact, and opportunity when mapping any standard lead picklist fields that are blank. If your organization uses record types, blank values are replaced with the default picklist values of the new record owner.
  • Automatic feed subscriptions: When you convert a lead into a new account, contact, and opportunity, the lead owner is unsubscribed from the lead account. The lead owner, the owner of the generated records, and users that were subscribed to the lead aren’t automatically subscribed to the generated records, unless they have automatic subscriptions enabled in their Chatter feed settings. They must have automatic subscriptions enabled to see changes to the account, contact, and opportunity records in their news feed. To subscribe to records they create, users must enable the Automatically follow records that I create option in their personal settings. A user can subscribe to a record so that changes to the record display in the news feed on the user's home page. This is a useful way to stay up-to-date with changes to records in Salesforce.
-----------------------------------------------------------------------------------------

LeadConvert Arguments

This call accepts an array of LeadConvert objects (100 maximum). A LeadConvert object contains the following properties.
NameTypeDescription
accountIdIDID of the Account into which the lead will be merged. Required only when updating an existing account, including person accounts. If no accountID is specified, then the API creates a new account. To create a new account, the client application must be logged in with sufficient access rights. To merge a lead into an existing account, the client application must be logged in with read/write access to the specified account. The account name and other existing data are not overwritten. For information on IDs, see ID Field Type.
contactIdIDID of the Contact into which the lead will be merged (this contact must be associated with the specified accountId, and an accountId must be specified). Required only when updating an existing contact.
Important
If you are converting a lead into a person account, do not specify the contactId or an error will result. Specify only the accountId of the person account.
If no contactID is specified, then the API creates a new contact that is implicitly associated with the Account. To create a new contact, the client application must be logged in with sufficient access rights. To merge a lead into an existing contact, the client application must be logged in with read/write access to the specified contact. The contact name and other existing data are not overwritten (unlessoverwriteLeadSource is set to true, in which case only the LeadSource field is overwritten).
convertedStatusstringValid LeadStatus value for a converted lead. Required. To obtain the list of possible values, the client application queries the LeadStatus object. For example:
1SELECT Id, MasterLabel
2FROM LeadStatus WHERE IsConverted=true
doNotCreateOpportunitybooleanSpecifies whether to create an Opportunity during lead conversion (false, the default) or not (true). Set this flag to true only if you do not want to create an opportunity from the lead. An opportunity is created by default.
leadIdIDID of the Lead to convert. Required. For information on IDs, see ID Field Type.
opportunityNamestringName of the opportunity to create. If no name is specified, then this value defaults to the company name of the lead. The maximum length of this field is 80 characters. If doNotCreateOpportunity argument is true, then no Opportunity is created and this field must be left blank; otherwise, an error is returned.
overwriteLeadSourcebooleanSpecifies whether to overwrite the LeadSource field on the target Contact object with the contents of the LeadSource field in the source Lead object (true), or not (false, the default). To set this field to true, the client application must specify acontactId for the target contact.
ownerIdIDSpecifies the ID of the person to own any newly created account, contact, and opportunity. If the client application does not specify this value, then the owner of the new object will be the owner of the lead. Not applicable when merging with existing objects—if an ownerId is specified, the API does not overwrite the ownerIdfield in an existing account or contact. For information on IDs, see ID Field Type.
sendNotificationEmailbooleanSpecifies whether to send a notification email to the owner specified in theownerId (true) or not (false, the default).

Counters