function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JBabuJBabu 

Getting FIELD_INTEGRITY_EXCEPTION, (pricebook entry is in a different pricebook ..)

Hi,

 

I am trying to insert test data as shown below:

 

(A)

  public static List<PriceBookEntry> pricebookentries(Integer quantity) {
     
     List <PriceBook2> pb2list = new List<PriceBook2>();
     List <Product2> prodlist = new List<Product2>();
     List <PriceBookEntry> pbelist = new List<PriceBookEntry>();
     List <PriceBookEntry> stdPbelist = new List<PriceBookEntry>();
   
     Pricebook2 standardPb = [select id, name, isActive from Pricebook2 where isStandard=true];
     system.assert(standardPb!=null);
     for (Integer j = 0; j<quantity; j++){
       pb2list.add(new PriceBook2(Name = 'Test Price Book' +j, isActive = true));
     }
     insert pb2list;
     
     for (Integer j = 0; j < quantity; j++) {
       Property__c property = PropertyUtil.findByName('American Express');
       prodlist.add(new Product2(Name = 'Test Product' +j, productCode = property.Business_Unit_Code__c, isActive = true, Property__c = property.Id));
     }
     insert prodlist;
     
     for (Integer j = 0; j < quantity; j++) {
       stdPbelist.add(new PriceBookEntry(Pricebook2Id=standardPb.id, Product2Id=prodlist.get(j).id, UnitPrice=99, isActive=true, UseStandardPrice=false));
     }
     insert stdPbelist;     
     
     for (Integer j = 0; j < quantity; j++) {
       pbelist.add(new PriceBookEntry(Pricebook2Id=pb2list.get(j).id, Product2Id=prodlist.get(j).id, UnitPrice=99, isActive=true, UseStandardPrice=false));
     }
     
     insert pbelist;
     system.debug('Price Book Entry Size');
     system.debug(pbelist.size());
     
     return pbelist;
  }
    

(B)

    public static List<OpportunityLineItem> createOpportunityLineItems(Integer quantity, List<PriceBookEntry> pbes,
            List<Opportunity> opps) {
        List<OpportunityLineItem> opplineitems = new List<OpportunityLineItem>();
        
        for (Integer i = 0; i < quantity; i++) {        
            opplineitems.add(new OpportunityLineItem(Line_Item_Name__c = 'Test Opportunity Line Item' +i,
                OpportunityId  =  opps[i].Id,
                PricebookentryId =  pbes[i].Id,
                Discount = 2,
                Quantity = i,
                TotalPrice = 1000,
                Start_Date__c = Date.newInstance(2012, 01, 01),
                End_Date__C = Date.newInstance(2020, 12, 31)
                ));
                
        }
        return opplineitems;
     }
          
After caling (A) code snippet I am calling (B) to test inserting multiple records in to opp line items.

But I am getting the below issue:

 

 

"System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]"

 

Even though I am passing the same price book entry id to the price book entry id of opp line items (in "createOpportunityLineItems" method) which was used to insert in to price book entries :

"PricebookentryId =  pbes[i].Id"

 

I am calling (A) and (B) in a separate test  class (C) as shown below:

 

(C)

private class TestOpportunityLineItemTrigger {
   private static final Integer ACCOUNT_RECORD_COUNT = 10;
   private static final Integer OPP_RECORD_COUNT = 20;
   private static final Integer OPP_LINE_ITEM_RECORD_COUNT = 20;
   private static final Integer PRICE_BOOK_PRODUCT_COUNT = 20;
    
 
   private static testmethod void testInsertandUpdates() {
 
    Map<String, List<Account>> accounts =
                SampleDataGenerator.createAccounts(ACCOUNT_RECORD_COUNT, false,
                true);
    
    Test.startTest();
    List <PricebookEntry> pricebookentryList =
            SampleDataGenerator.pricebookentries(PRICE_BOOK_PRODUCT_COUNT);     

    List <Opportunity> oppsToInsert =
            SampleDataGenerator.createOpportunities(OPP_RECORD_COUNT,
                    accounts, false);
    for (Integer i = 0 ; i < oppsToInsert.size(); i++) {
        oppsToInsert[i].Opportunity_Name__c = 'Test Opp ' + i;
    }
    insert oppsToInsert;
    
    OpportunityLineItem[] opplineitemsToInsert =
        SampleDataGenerator.createOpportunityLineItems(OPP_LINE_ITEM_RECORD_COUNT, pricebookentryList,
                        oppsToInsert);   

}

 

 

Please help me on this issue.

 

Thanks,

JBabu.


Best Answer chosen by Admin (Salesforce Developers) 
TheIntegratorTheIntegrator

ok, first thing, you don't seem to be setting the price book for opportunities

 

Update your function createOpportunities and pass pricebookentryList , then in opportunities.add you will need to assign Pricebook2Id

 

secondly, I'm not sure if this will gurantee that pricebook in opportunity line matches that of opportunity because of the loop structure. If it doesn't you might have to rewrite the for loop in createOpportunityLineItems or atleast put a check opps[i].Pricebook2Id ==  pbes[i].Id before they are assigned to opplineitems fields.

 

Let me know if this solves, or if you have any other questions.

All Answers

TheIntegratorTheIntegrator

Can you share how you are populating pbes and opps with the call to createOpportunityLineItems

JBabuJBabu

I am using the below code to call them:

 

private class TestOpportunityLineItemTrigger {
   private static final Integer ACCOUNT_RECORD_COUNT = 10;
   private static final Integer OPP_RECORD_COUNT = 20;
   private static final Integer OPP_LINE_ITEM_RECORD_COUNT = 20;
   private static final Integer PRICE_BOOK_PRODUCT_COUNT = 20;
    
 
   private static testmethod void testInsertandUpdates() {
 

    Test.startTest();
    List <PricebookEntry> pricebookentryList =
            SampleDataGenerator.pricebookentries(PRICE_BOOK_PRODUCT_COUNT);     

    List <Opportunity> oppsToInsert =
            SampleDataGenerator.createOpportunities(OPP_RECORD_COUNT,
                    accounts, false);
    for (Integer i = 0 ; i < oppsToInsert.size(); i++) {
        oppsToInsert[i].Opportunity_Name__c = 'Test Opp ' + i;
    }
    insert oppsToInsert;
    
    OpportunityLineItem[] opplineitemsToInsert =
        SampleDataGenerator.createOpportunityLineItems(OPP_LINE_ITEM_RECORD_COUNT, pricebookentryList,
                        oppsToInsert);   

}

 

JBabuJBabu

I am using SampleDataGenerator class, in which (A) and (B) are methods of it.

TheIntegratorTheIntegrator

Can you also share the function createOpportunities

JBabuJBabu

CreateOpportunities function:

 

    public static List<Opportunity> createOpportunities(Integer quantity,
            Map<String, List<Account>> accountsMap) {
        List<Opportunity> opportunities = new List<Opportunity>();
        List<User> users = [select Id from User where IsActive = true
                limit :quantity];        
        for (Integer i = 0; i < quantity; i++) {
            opportunities.add(new Opportunity(Name = 'Test Opportunity ' + i,
                    AccountId = accountsMap.get('ABC)[Math.mod(i,
                            accountsMap.get('ABC').size())].Id,
                    CloseDate = Date.newInstance(2099, 12, 31),
                    StageName = '10% - Engaged',
                    Schedule_Start_Date__c =
                            Date.newInstance(2099, 1, 1),
                    End_Date__c = Date.newInstance(2099, 1, 31),
                    Amount = 10000,
                    OwnerId = users[Math.mod(i, users.size())].Id));
        }

}

TheIntegratorTheIntegrator

ok, first thing, you don't seem to be setting the price book for opportunities

 

Update your function createOpportunities and pass pricebookentryList , then in opportunities.add you will need to assign Pricebook2Id

 

secondly, I'm not sure if this will gurantee that pricebook in opportunity line matches that of opportunity because of the loop structure. If it doesn't you might have to rewrite the for loop in createOpportunityLineItems or atleast put a check opps[i].Pricebook2Id ==  pbes[i].Id before they are assigned to opplineitems fields.

 

Let me know if this solves, or if you have any other questions.

This was selected as the best answer
JBabuJBabu

thank you.. it worked when I updated the createOpportunties function..