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
Kevin Kim 9Kevin Kim 9 

How to copy over opportunity products to a custom object

I am trying to copy over my opportunity products to a custom object (projects) by clicking a button. What does the code look like for that? I am very new to salesforce apex coding. 
Best Answer chosen by Kevin Kim 9
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

You will find it difficult to copy all Opportunity Product records into a single Project. I believe the data model must be a little different

Project

-> Project Products

 

Assuming this updated model please try the following code

global class buttonHandler{ 
   	Webservice static void copyOLItoPP(String strRecId){
		list<ProjectProduct> lstPP = new list<ProjectProduct>();
		List<OpportunityLineItem> lstOLI = [Select .... from OpportunityLineItem where OpportunityId =: strRecId];
		if(lstOLI != null && !lstOLI.isEmpty()){
			Project objProject = new Project();
			// map mandatory fields
			insert objProject;
			
			for(OpportunityLineItem objQ : lstOLI){
				ProjectProduct objProd = new ProjectProduct();
				// mapp all fields
				objProd.Project__c = objProject.Id;
				lstPP.add(objProd);
			}
			if(!lstPP.isEmpty(){
				insert lstPP;
			}
		}
	}
}

Custom button code

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")} 
sforce.apex.execute("buttonHandler","copyOLItoPP",{id:"{!Quote.Id}"}); 
location.reload();


Thanks

Vivian

All Answers

Vivian Charlie 1208Vivian Charlie 1208

Hi Kevin,

Do you wish to have the button on the OpportunityProduct so that clicking it copies the details to create a single Project record?

OR

Do you wish to have the button on Opportunity so that clicking it copies all related products and create a project record for every product?

 

Thanks
Vivian

Kevin Kim 9Kevin Kim 9
I would like it to copy all the related products to a single Project record
Kevin Kim 9Kevin Kim 9
I would like to have a button on the Opportunity but having it on the Opportunity Product is fine. Whichever is easier I guess
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

You will find it difficult to copy all Opportunity Product records into a single Project. I believe the data model must be a little different

Project

-> Project Products

 

Assuming this updated model please try the following code

global class buttonHandler{ 
   	Webservice static void copyOLItoPP(String strRecId){
		list<ProjectProduct> lstPP = new list<ProjectProduct>();
		List<OpportunityLineItem> lstOLI = [Select .... from OpportunityLineItem where OpportunityId =: strRecId];
		if(lstOLI != null && !lstOLI.isEmpty()){
			Project objProject = new Project();
			// map mandatory fields
			insert objProject;
			
			for(OpportunityLineItem objQ : lstOLI){
				ProjectProduct objProd = new ProjectProduct();
				// mapp all fields
				objProd.Project__c = objProject.Id;
				lstPP.add(objProd);
			}
			if(!lstPP.isEmpty(){
				insert lstPP;
			}
		}
	}
}

Custom button code

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")} 
sforce.apex.execute("buttonHandler","copyOLItoPP",{id:"{!Quote.Id}"}); 
location.reload();


Thanks

Vivian

This was selected as the best answer
Kevin Kim 9Kevin Kim 9
Probably a rookie mistake but I keep getting an error on line 3 invalid type: ProjectProduct
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

The above code is not an actual code, it is a pseudo code. Change the custom object to include __c in the api name

global class buttonHandler{
        Webservice static void copyOLItoPP(String strRecId){
		list<ProjectProduct__c> lstPP = new list<ProjectProduct__c>();
		List<OpportunityLineItem> lstOLI = [Select .... from OpportunityLineItem where OpportunityId =: strRecId];
		if(lstOLI != null && !lstOLI.isEmpty()){
			Project__c objProject = new Project__c();
			// map mandatory fields
			insert objProject;
			
			for(OpportunityLineItem objQ : lstOLI){
				ProjectProduct__c objProd = new ProjectProduct__c();
				// mapp all fields
				objProd.Project__c = objProject.Id;
				lstPP.add(objProd);
			}
			if(!lstPP.isEmpty(){
				insert lstPP;
			}
		}
	}
}

Thanks

Vivian

Kevin Kim 9Kevin Kim 9
Does that mean I am making ProjectProduct as a new custom object or a new custom field?
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

Project__c : Parent object

ProjectProduct__c : Child object // relation can be Lookup or Master Detail

 

Thanks

Vivian

Kevin Kim 9Kevin Kim 9
Vivian, 

I am now getting an error that says "entity is not api accessible entity name: Project"
I double checked to make sure all my api names were correct and they seem to be so I dont know why im getting this error
Seriously thank you for helping me through this
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

Have you created Project__c object and ProjectProduct__c object in your salesforce environment? Did you establish a relationship between the 2 objects?

 

Thanks

Vivian

Kevin Kim 9Kevin Kim 9
Yes, I created a master-detail relationship between ProjectProduct__c and Project__c where Project__c is the master (parent)
Kevin Kim 9Kevin Kim 9
I forgot to change one of the Project to Project__c but I still am getting an error which says:
Line 13 Invalid field Project__c for sObject ProjectProduct__c
 
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

Replace objProd.Project__c with the objProd.YourMasterDetail__c field name

 

Thanks

Vivian

 

Kevin Kim 9Kevin Kim 9
That worked. Now when it comes to the button am I using that code as a URL (probably not) or am I using it as OnClick Javascript?
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

Use the button as an onClick javascript. Replace {!Quote.Id} with {!OpportunityId} from the Opportunity object.

 

Thanks

Vivian

Kevin Kim 9Kevin Kim 9
I replaced Quote with Opportunity but I still get an error that says:

A problem with the Onclick Javascript button was encountered:

{faultcode:'soapenv:Client; faultstring:'No such parameter id defined for operation. please check the WSDL for the service.'}
Kevin Kim 9Kevin Kim 9
Do I have to make a relationship between Opportunity and Project custom objects?
Vivian Charlie 1208Vivian Charlie 1208
Kevin, It would be preferable to have a relationship between Opportunity and Project, we can set that up later. Can you shared the button code, which object it is created on and what type of button it is.
Kevin Kim 9Kevin Kim 9
I created a button on the Opportunities object. The button is a detail page button and the only code that is in the code portion is the segment of code that you gave me with the above mentioned changes.

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")} 
sforce.apex.execute("buttonHandler","copyOLItoPP",{id:"{!Opportunity.Id}"}); 
location.reload();

 
Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

In case you have a developer environment would you be able to share the developer environment credentials so that I can investigate why you are facing this issue.

You can send the credentials at vivian.charlie1208@gmail.com

 

Thanks

Vivian

Vivian Charlie 1208Vivian Charlie 1208

Kevin,

 

Following is the updated button code

{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")} 
var strRecId = "{!Opportunity.Id}"; 
alert('********'+strRecId); 
sforce.apex.execute("buttonHandler","copyOLItoPP",{strRecId:strRecId}); 
window.location.reload();


In case your issue has been resolved please feel free to mark this as closed.

 

Thanks

Vivian

rizki asharirizki ashari
Hi Vivian,

Can you also explain how to do the testing and deploy the changes to production?

Rizki