This post is a part of the daily blog series
A Tip A Day, daily dosage of learning!
Day #21 – PriceBookEntry Creation with StandardPrice
We have a Product with a standard price of say $100. As shown below, in Salesforce UI, it is easy to add a product and add a standard price (related list). We can also associate the Product to another custom Price Book by clicking on the Add to Price Book button in Price Books related list.
Note here that the custom price book entry has the checkbox “Use Standard Price” ticked which implies that if the standard price is changed for this product, the custom price book entry will also reflect the same. This is a very useful feature.
Requirement
Now the requirement is that we need to do the same via API as in an Apex class or an Apex trigger automatically. This sounds simple, but there is a catch!
Attempt 1: If you do simple pricebookentry creation like this:
PricebookEntry pbe = new PricebookEntry(
Pricebook2Id='xxxxxx',
IsActive=true,
Product2Id='xxxxxx',
UseStandardPrice=true
);
insert pbe;
You’d get this error
Error 1: REQUIRED_FIELD_MISSING, Required fields are missing: [UnitPrice]: [UnitPrice]
Attempt 2: Okay, so I add the UnitPrice, but then it gives another error
PricebookEntry pbe = new PricebookEntry(
Pricebook2Id='xxxxx',
IsActive=true,
Product2Id='xxxxx',
UseStandardPrice=true,
UnitPrice = 0.70
);
insert pbe;
Error 2: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception
Attempt 3: I read that UseStandardPrice==true
cannot be set. It has to be false as per the help document help.salesforce.com/articleView?id=000193277&type=1
PricebookEntry pbe = new PricebookEntry(
Pricebook2Id='xxxxx',
IsActive=true,
Product2Id='xxxxx',
UseStandardPrice=false,
UnitPrice = 0.70
);
insert pbe;
Result: Setting it to False actually inserts the record. But I want it to be set to true. No error, but not the solution as I want UseStandardPrice==true
Final Solution
I have figured out that we cannot set UseStandardPrice=true
on insert. On insert it has to be set to False first, along with mentioning UnitPrice
. Then later do an additional update to set the UseStandardPrice=false
PricebookEntry pbe = new PricebookEntry(
Pricebook2Id='xxxxx',
IsActive=true,
Product2Id='xxxxx',
UseStandardPrice=false,
UnitPrice = 0.70
);
insert pbe;
pbe.UseStandardPrice = true;
update pbe;
There you go! Perfect. It worked. 2 DMLs though, but it works.
Here’s the full code if you want to do the same in a test class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//product1 | |
Product2 p = new Product2(); | |
p.Name = 'Test Product'; | |
p.Description = 'Test desc'; | |
p.IsActive = true; | |
insert p; | |
//standard price book entry for Product p | |
PricebookEntry pbe1 = new PricebookEntry(); | |
pbe1.Pricebook2Id = Test.getStandardPricebookId(); | |
pbe1.IsActive = true; | |
pbe1.Product2Id = p.Id; | |
pbe1.UseStandardPrice = false; | |
pbe1.CurrencyISOCode = 'SGD'; | |
pbe1.UnitPrice = 100; | |
insert pbe1; | |
//custom pricebook | |
PriceBook2 pb = new PriceBook2(); | |
pb.Name = 'Custom PB'; | |
pb.IsActive = true; | |
insert pb; | |
//custom pricebook entry for p1 | |
PricebookEntry pbe = new PricebookEntry(); | |
pbe.Pricebook2Id = pb.Id; | |
pbe.IsActive = true; | |
pbe.Product2Id = p.Id; | |
pbe.UseStandardPrice = false; | |
pbe.CurrencyISOCode = 'SGD'; | |
pbe.UnitPrice = 100; | |
insert pbe; | |
//update Pricebookentry to use Standard Price | |
pbe.UseStandardPrice = true; | |
update pbe; |
One Reply to “A Tip A Day #21 – PriceBookEntry Creation with StandardPrice”