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
H 007H 007 

Hi I need a batch class to insert 10 Opportunity line items on each closed Won Opportunity exists in your org.

global class BatchOnContact implements Database.Batchable<sObject>, Database.Stateful{
    
    global Database.QueryLocator start(Database.BatchableContext bc){     
        
        return Database.getQueryLocator('select Id, name, StageName from opportunity where StageName=\'Closed Won\'');
        
    }
    global void execute(Database.BatchableContext bc, List<opportunity> Opplist){
        List<OpportunityLineItem> OList = new List<OpportunityLineItem>();
        List<Product2> prolist= [SELECT Id from Product2 Limit 10];
              For(opportunity opp:  Opplist){
            for(Integer i=0; i<10; i++){
               OpportunityLineItem op= new OpportunityLineItem(opportunityId=opp.id, Product2Id=prolist.get(i).id,Quantity =1, TotalPrice=1000);
                OList.add(op);                                                               
            }  opp.Pricebook2Id='0066F00000yUeDpQAK';            
        }update opplist;
        insert OList;      
    }
 global void finish(Database.BatchableContext bc){ }
}
Best Answer chosen by H 007
CharuDuttCharuDutt
Hii Harsh
Try Below i've Changed Code
global class BatchOnContact implements Database.Batchable<sObject>, Database.Stateful{
    
    global Database.QueryLocator start(Database.BatchableContext bc){     
        
        return Database.getQueryLocator('select Id, name, StageName from opportunity where StageName=\'Closed Won\'');
        
    }
    global void execute(Database.BatchableContext bc, List<opportunity> Opplist){
        List<PriceBookEntry> Opbe = new List<PriceBookEntry>();
        List<OpportunityLineItem> OList = new List<OpportunityLineItem>();
        List<Product2> Oproduct = new List<Product2>();
        map<string,string> idWiseoppPRoductMap = new map<string,string>();
        Pricebook2 stdPriceBook  = [select id, name,isActive,IsArchived from Pricebook2 where isStandard = true limit 1];
        stdPriceBook.isActive = true;
        update stdPriceBook;
        
        For(opportunity opp:  Opplist){
            for(Integer i=0; i<10; i++){
                Product2 p = new Product2();
                p.Name = opp.Name;
                p.Description = opp.Id;
                p.isActive = true;
                Oproduct.add(p);

                                     
                    }             
        }
        if(!Oproduct.isEmpty()){
            insert Oproduct;
            for(Product2 oPro : Oproduct){
                idWiseoppPRoductMap.put(oPro.Id, oPro.Description);
                PriceBookEntry customPriceBookEntry  = new PriceBookEntry();
                customPriceBookEntry.Product2Id = oPro.Id;
                customPriceBookEntry.Pricebook2Id = stdPriceBook.Id;
                customPriceBookEntry.UnitPrice = 5000;
                customPriceBookEntry.IsActive = true;
                
                Opbe.add(customPriceBookEntry);
            }
        }
        
        if(!Opbe.isEmpty()){
            insert Opbe;
            for(PriceBookEntry oPbe2 : Opbe){
                OpportunityLineItem oppLineItem = new OpportunityLineItem();
                oppLineItem.OpportunityId = idWiseoppPRoductMap.get(oPbe2.Product2Id);
                oppLineItem.PricebookEntryId = oPbe2.Id;
                oppLineItem.Quantity = 5;
                oppLineItem.UnitPrice = 1000;
                OList.add(oppLineItem);               
            }
        }
           if(!OList.isEmpty()){
            insert OList;
        }
    }
    global void finish(Database.BatchableContext bc){ }
}
Please Mark It As Best Asnwer If It Helps
Thank You!

 

All Answers

CharuDuttCharuDutt
Hii Harsh
Try Below Code
global class BatchOnContact implements Database.Batchable<sObject>, Database.Stateful{
    
    global Database.QueryLocator start(Database.BatchableContext bc){     
        
        return Database.getQueryLocator('select Id, name, StageName from opportunity where StageName=\'Closed Won\'');
        
    }
    global void execute(Database.BatchableContext bc, List<opportunity> Opplist){
        List<OpportunityLineItem> OList = new List<OpportunityLineItem>();
        
        Pricebook2 stdPriceBook  = [select id, name,isActive,IsArchived from Pricebook2 where isStandard = true limit 1];
        stdPriceBook.isActive = true;
        update stdPriceBook;
        
        For(opportunity opp:  Opplist){
            for(Integer i=0; i<10; i++){
                Product2 p = new Product2();
                p.Name = opp.Name;
                p.Description = opp.Name;
                p.isActive = true;
                insert p;

                PriceBookEntry customPriceBookEntry  = new PriceBookEntry();
                customPriceBookEntry.Product2Id = p.Id;
                customPriceBookEntry.Pricebook2Id = stdPriceBook.Id;
                customPriceBookEntry.UnitPrice = 5000;
                customPriceBookEntry.IsActive = true;
                insert customPriceBookEntry;
                
                OpportunityLineItem oppLineItem = new OpportunityLineItem();
                oppLineItem.OpportunityId = opp.Id;
                oppLineItem.PricebookEntryId = customPriceBookEntry.Id;
                oppLineItem.Quantity = 5;
                oppLineItem.UnitPrice = 1000;
                OList.add(oppLineItem)                        
                    }             
        }
        if(!OList.isEmpty()){
            insert OList;
        }
    }
    global void finish(Database.BatchableContext bc){ }
}
Please Mark It As Best Asnwer If It Helps
Thank You!
H 007H 007
Hi Charu, thank you for your reply but Too_ Many_ DML statements error are shown.. Can you please help me..
CharuDuttCharuDutt
Hii Harsh
Try Below i've Changed Code
global class BatchOnContact implements Database.Batchable<sObject>, Database.Stateful{
    
    global Database.QueryLocator start(Database.BatchableContext bc){     
        
        return Database.getQueryLocator('select Id, name, StageName from opportunity where StageName=\'Closed Won\'');
        
    }
    global void execute(Database.BatchableContext bc, List<opportunity> Opplist){
        List<PriceBookEntry> Opbe = new List<PriceBookEntry>();
        List<OpportunityLineItem> OList = new List<OpportunityLineItem>();
        List<Product2> Oproduct = new List<Product2>();
        map<string,string> idWiseoppPRoductMap = new map<string,string>();
        Pricebook2 stdPriceBook  = [select id, name,isActive,IsArchived from Pricebook2 where isStandard = true limit 1];
        stdPriceBook.isActive = true;
        update stdPriceBook;
        
        For(opportunity opp:  Opplist){
            for(Integer i=0; i<10; i++){
                Product2 p = new Product2();
                p.Name = opp.Name;
                p.Description = opp.Id;
                p.isActive = true;
                Oproduct.add(p);

                                     
                    }             
        }
        if(!Oproduct.isEmpty()){
            insert Oproduct;
            for(Product2 oPro : Oproduct){
                idWiseoppPRoductMap.put(oPro.Id, oPro.Description);
                PriceBookEntry customPriceBookEntry  = new PriceBookEntry();
                customPriceBookEntry.Product2Id = oPro.Id;
                customPriceBookEntry.Pricebook2Id = stdPriceBook.Id;
                customPriceBookEntry.UnitPrice = 5000;
                customPriceBookEntry.IsActive = true;
                
                Opbe.add(customPriceBookEntry);
            }
        }
        
        if(!Opbe.isEmpty()){
            insert Opbe;
            for(PriceBookEntry oPbe2 : Opbe){
                OpportunityLineItem oppLineItem = new OpportunityLineItem();
                oppLineItem.OpportunityId = idWiseoppPRoductMap.get(oPbe2.Product2Id);
                oppLineItem.PricebookEntryId = oPbe2.Id;
                oppLineItem.Quantity = 5;
                oppLineItem.UnitPrice = 1000;
                OList.add(oppLineItem);               
            }
        }
           if(!OList.isEmpty()){
            insert OList;
        }
    }
    global void finish(Database.BatchableContext bc){ }
}
Please Mark It As Best Asnwer If It Helps
Thank You!

 
This was selected as the best answer
H 007H 007
Follwoing Error is Shown.. 
User-added image
H 007H 007
FATAL_ERROR|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]
CharuDuttCharuDutt

Hii Harsh
Working Fine In My Org Check If There's Any Process
User-added image

Maharajan CMaharajan C
Hi Harsh,

The error is stating: you are adding the products under some opportunity as lineitem where opportunity is already linked with different Pricebook and the Product you are adding under that opportunity having different Pricebook Id that is standard pricebook.  

So i will suggest you keep atleast 10 products under all pricebooks then execute the batch... Otherwise you have to write big logic inside your apex... Better keep it simple add dummy products in your org itself and add those products under pricebooks whicj having 10 lesser entry count.

Once your data work done you can execute the below batch:
 
global class BatchOnContact implements Database.Batchable<sObject>, Database.Stateful{
    
    global Database.QueryLocator start(Database.BatchableContext bc){     
        
        return Database.getQueryLocator('select Id, name, StageName,Pricebook2Id from opportunity where StageName=\'Closed Won\'');
        
    }
    global void execute(Database.BatchableContext bc, List<opportunity> Opplist){
        
        List<OpportunityLineItem> opltoInsert = new List<OpportunityLineItem>();        
        
        Pricebook2 stdPriceBook  = [select id, name,isActive,IsArchived from Pricebook2 where isStandard = true limit 1];
        if(!stdPriceBook.isActive){
            stdPriceBook.isActive = true;
            update stdPriceBook;
        }
        
        Map<Id,Id> oppPriceBookMap = new Map<Id,Id>();
        Set<Id> Pricebook2Ids = new Set<Id>();
        for(opportunity opp:  Opplist){
            if(opp.Pricebook2Id != null){
                Pricebook2Ids.add(opp.Pricebook2Id);
                oppPriceBookMap.put(opp.Id, opp.Pricebook2Id);
            }         
            else
            {
                oppPriceBookMap.put(opp.Id, stdPriceBook.Id);
                Pricebook2Ids.add(stdPriceBook.Id);
            }
        }
        
        List<PricebookEntry> pbEntries = [Select Id,Product2Id,Pricebook2Id,UnitPrice from PricebookEntry where  Pricebook2Id IN: Pricebook2Ids];
        Map<Id, List<PricebookEntry>> pbEntriesMap = new Map<Id, List<PricebookEntry>>();
        for(PricebookEntry pbe : pbEntries){
            If(!pbEntriesMap.containsKey(pbe.Pricebook2Id))
                pbEntriesMap.put(pbe.Pricebook2Id, new List<PricebookEntry>{pbe});
            else
                pbEntriesMap.get(pbe.Pricebook2Id).add(pbe);
        }
        
        for(Id ids : oppPriceBookMap.keyset()){
            Id keyId = oppPriceBookMap.get(ids);
            if(pbEntriesMap.containsKey(keyId)){
                List<PricebookEntry> pbEntriesRecords = pbEntriesMap.get(keyId);
                for(Integer i=0; i<10; i++){
                    OpportunityLineItem opli= new OpportunityLineItem(opportunityId=ids ,TotalPrice = 1000.00 ,Quantity=1, PricebookEntryId = pbEntriesRecords[i].Id);
                    opltoInsert.add(opli);
                }
            }
        }
        
        if(!opltoInsert.IsEmpty())
            insert opltoInsert;
    }
    global void finish(Database.BatchableContext bc){ }
}


Thanks,
Maharajan.C