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
KunlunKunlun 

How can I add products into opportunitylineitem

I did a trigger to add products into opportunitylineitem

Code:
trigger AddProductList on Opportunity (after update, after insert) {
    Opportunity opp = new Opportunity();
    for (Opportunity oppty : System.Trigger.new) {
        opp = oppty;
    }
    String strProductName = 'A1_kevytmoottoripyorakotti';
    Product2 product = [select Tuotelista__c from Product2 where Name = :strProductName LIMIT 1];
    if(product != null)
    {
        String[] strProductList = product.Tuotelista__c.split(';', 0);
        List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();
        for(PriceBookEntry pbe : [select pbe.Id, pbe.Pricebook2Id, pbe.UnitPrice from PriceBookEntry pbe where pbe.Name in :strProductList])
        {
            OpportunityLineItem oli = new OpportunityLineItem
            (
                OpportunityId = opp.Id,
                PricebookEntryId = pbe.Id,
                Quantity = 1,
                UnitPrice = pbe.UnitPrice,
                ServiceDate = System.today()
            );
            oliList.add(oli);
        }
        insert oliList;
    }
    
    
}

 When user save opportunity, I will select some products and add them into opportunityLineItem.
But it threw an error message like below:
Insert failed. First exception on row 1; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]: Trigger.AddProductList: line 45, column 9
What does that mean? Can't I add different pricebook into opportunityLineItem?
How can I write code to add products into opportunityLineItem?
JimRaeJimRae
An opportunity can only be based on one pricebook at a time.  In order to do what you are requesting, you will need to find out what pricebook was used for any existing products, and add your product from there.  This will mean the product you are adding must exist, or be added to the pricebook being used.
jeffdonthemicjeffdonthemic
Not sure if this will help but here is a partial test case I wrote some time ago.

Code:
public static testMethod void testMe() {
   
    Pricebook2 s = [select id from Pricebook2 where IsStandard = true];   
    
    // create the product
    Product2 p1 = new Product2(
        name='Test Product 1',
        IsActive=true,
        Description='My Product',
        RecordTypeId='01260000000Dxxx',
        ProductCode='12345'
    );
    insert p1;       
   
    // create the pricebookentry
    PricebookEntry pbe1 = new PricebookEntry(
        Pricebook2Id=s.id,
        Product2Id=p1.id,
        UnitPrice=0.00,
        IsActive=true,
        UseStandardPrice=false
    );
    insert pbe1;   
   
    // create the opportunity
    Opportunity opp1 = new Opportunity(
        name='Test Opp 1',
        recordtypeid='01260000000DXrWxxx',
        StageName = 'Identify',
        CloseDate = Date.newInstance(2009,01,01)            
    );
    insert opp1;
   
    // add the line item
    OpportunityLineItem oli = new OpportunityLineItem();
    oli.Quantity = 1;
    oli.TotalPrice = 1;
    oli.PricebookEntryId = pbe1.id;
    oli.OpportunityId = opp1.id;    
    insert oli;   
   
}

 

Jeff Douglas
Informa Plc
http://blog.jeffdouglas.com
BhawnaBhawna

Hi,

 

Have you resove the issue; as I'm too facing the same problem and confused what to do now.....

Please guide me ..... I'll be very thankful to you..

 

waiting for reply...

 

 

Bhawna...

goabhigogoabhigo

Hi,

Did you find solution for this? If yes please post it.

goabhigogoabhigo

Whats wrong in my code?

 

public static testMethod void testMyController() {
        Pricebook2 stdPb = [select Id from Pricebook2 where isStandard=true limit 1];
        
        Product2 p = new product2(name='Abhi',family='Abhi',productcode='12345');
        insert p;
        System.debug('### p:'+p);
        
        PricebookEntry pbe = new PricebookEntry(pricebook2id=stdPb.id, product2id=p.id, 
                                              unitprice=1.0, isActive=true,UseStandardPrice=false);
        insert pbe;
        
        Opportunity o = new Opportunity(name='test',
                  stageName='Open', CloseDate=Date.newInstance(2006,10,10));
        insert o;
        //OpportunityLineItem oli = new OpportunityLineItem(opportunityid=o.id, 
        //                        pricebookentryid=pbe.id, unitprice=1.5, quantity=2);
        //insert oli;
        Quote q = new  Quote(opportunityid = o.id,name='test Method'); 
        insert q;
        System.debug('### q: ' + q);
        QuoteLineItem qli = new QuoteLineItem(quoteId=q.Id,
                                pricebookentryid=pbe.id, unitprice=1.5, quantity=2);
        insert qli;
        InvoiceController ctrl = new InvoiceController(new ApexPages.StandardController(q));
        ctrl.getResults();
        ctrl.updateQLIField();
        ctrl.getCurrentQuoteObj();
     }
}

 

 

I am getting error for the highlighted line:

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, The pricebook entry is in a different pricebook than the one assigned to the Quote, or Quote has no pricebook assigned.: [PricebookEntryId]

 

Please suggest me.

 

 

 

JimRaeJimRae

Looks like you need to include the Pricebook on your quote when you create it.

 

 

Quote q = new  Quote(opportunityid = o.id,name='test Method',pricebookid=stdPb.id); 

 

 

goabhigogoabhigo

Thanks Jim. It worked for me.

It should be pricebook2id=stdPb.id

MrBlueSkyMrBlueSky

For anyone else using Jeff's useful snippet of test code, you need to be aware that you cannot by default see the pricebooks from test code.  You need to make sure that the test case is flagged with SeeAllData=true

 

Ref: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm