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
MigMig 

Clone Opportunity w/wo related objects

I'm developing new buttons at the Opportunity Level that will clone the Opportunity with or without some related objects !

The clone works fine (at least I think this is the best way to do it )


Opportunity opp=[Select o.qtyProductGroups__c, o.Won_Lost_Comment__c, o.State__c, o.StageName, o.Selected_Contact_Id__c, o.Remarks__c, o.RecordTypeId, o.Reason_Won__c, o.Reason_Lost__c, o.Probability, o.Primary_Opportunity__c, o.Pricebook2Id, o.Personal_Chance_of_Success__c, o.OwnerId, o.Opportunity_Type__c, o.Opportunity_Description__c, o.One_Shot_Order__c, o.IsWon, o.IsDeleted, o.IsClosed,
o.I_Internal_Status__c, o.I_Account_manager__c, o.HasOpportunityLineItem, o.ForecastCategoryName, o.ForecastCategory, o.FiscalYear,
o.FiscalQuarter, o.Fiscal, o.FAS__c, o.Expire_Date__c, o.Do_not_Show_Total__c, o.Description, o.Delivery_specifications__c, o.Customer_Reference__c, o.CurrencyIsoCode, o.Contractual_Agreement__c, o.Competitor__c, o.Competitor_Products_involved__c, o.Competitor_Pricing__c, o.Competition__c, o.CloseDate, o.Categorisation__c, o.Budget__c, o.Amount, o.AccountId From Opportunity o where id=:getOpportunityId()];
if (opp.Id != null){
Opportunity newOpp = opp.clone(false,true);
newOpp.Name=opp.Name + ' CLONE';
insert newOpp;
}



As you see I need to put in there all the fields to be cloned.
The problem is : if in the future I create a new field, this one will not be transmitted with the clone ! (unless I edit the query here and add this new field) !!!!!! Is there any solution for this ?


Tkx a lot to you all for your answers and support !

Message Edited by Mig on 01-19-2009 06:49 PM
Best Answer chosen by Admin (Salesforce Developers) 
aalbertaalbert
Here is an example:
Code:
// Get the sObject describe result for the Opportunity object
Schema.DescribeSObjectResult r = Opportunity.sObjectType.getDescribe();

//Generate a Map of the fields
Map<String, Schema.SObjectField> M = r.fields.getMap();

//Now loop through the list of Field Names and concatenate the SOQL query string
String SOQL = 'Select '; 
for (String fieldName : M.keySet()){
   System.debug('fieldName: ' + fieldName);
   SOQL += fieldName + ',';  
} 

//Remove the last , unnecessary comma
SOQL = SOQL.substring(0,SOQL.length()-1);

//Append the FROM and WHERE clause, using LIMIT 1 as an example
SOQL += ' From Opportunity LIMIT 1';

//Execute SOQL
sObject S = Database.query(SOQL);

//Cast the sObject type into an Opportunity
Opportunity o = (Opportunity)S;

 

All Answers

aalbertaalbert
Yes, check out the documentation on Dynamic Apex: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dynamic.htm


You can perform the DescribeSObject for the set of Objects you need to generate the list of fields for. Then construct your SOQL string and execute the Query. For example:

List<sObject> L = Database.query(string);

MigMig
Ohh yeah I see what you mean.
I can be able to loop into the Opportunity, pick all the field and copy the value ...
gonna try that and let you know if it works ... I suppose there are no samples of that ...

Thankx a lot aalbert ! =)
aalbertaalbert
Here is an example:
Code:
// Get the sObject describe result for the Opportunity object
Schema.DescribeSObjectResult r = Opportunity.sObjectType.getDescribe();

//Generate a Map of the fields
Map<String, Schema.SObjectField> M = r.fields.getMap();

//Now loop through the list of Field Names and concatenate the SOQL query string
String SOQL = 'Select '; 
for (String fieldName : M.keySet()){
   System.debug('fieldName: ' + fieldName);
   SOQL += fieldName + ',';  
} 

//Remove the last , unnecessary comma
SOQL = SOQL.substring(0,SOQL.length()-1);

//Append the FROM and WHERE clause, using LIMIT 1 as an example
SOQL += ' From Opportunity LIMIT 1';

//Execute SOQL
sObject S = Database.query(SOQL);

//Cast the sObject type into an Opportunity
Opportunity o = (Opportunity)S;

 

This was selected as the best answer
MigMig
Thanks a lot aalbert for your really quick answer and all the help you gave me...
I've just follow your example and it works nice =)
I'll pay you a beer next time =)


And to share it, here is the code :

Code:
public PageReference autoRun() {
String oppID = ApexPages.currentPage().getParameters().get('id');
if (oppID == null) {
// Display the Visualforce page's content if no Id is passed over
return null;
}
// Get the sObject describe result for the Opportunity object
Schema.DescribeSObjectResult r = Opportunity.sObjectType.getDescribe();
Map<String, Schema.SObjectField> M = r.fields.getMap(); //Generate a Map of the fields

//Now loop through the list of Field Names and concatenate the SOQL query string
String SOQL = 'Select ';
for (String fieldName : M.keySet()){
System.debug('fieldName: ' + fieldName);
SOQL += fieldName + ',';
}
SOQL = SOQL.substring(0,SOQL.length()-1); //Remove the last , unnecessary comma
SOQL += ' From Opportunity o where id=\''+getOpportunityId()+'\' LIMIT 1' ;

//Execute SOQL & Cast the sObject type into an Opportunity
sObject S = Database.query(SOQL);
Opportunity opp = (Opportunity)S;

//Clone the Opportunity - 2 parameters (PreserveId or not, IsDeepClone or not )
Opportunity newOpp = opp.clone(false,true);
newOpp.Name=opp.Name + ' v2';
insert newOpp;

/*.... All the other related objects like OpportunityLineItems : */

// Go to the new Opportunity
PageReference pageRef = new PageReference('/' + newOpp.Id);
pageRef.setRedirect(true);
return pageRef;


}

 
Cheers,
Mig




sgoremasgorema

hi - any chance you would be willing to share the code to copy the product line items as well? i am just starting on a project where i need to do just this (clone the oppty AND the line items). Any help would be so welcome!

 

 

withoutmewithoutme
do you use this as an extension to opp st controller  and create a vf page? I;m confused if the vf page should be a detail page or form when creating a clone button. as all the logic gets executed on click and a new record is created.
withoutmewithoutme
ok i figured it out, i dint realise the <apex:page> tag has action attribute to use. makes life easier. thanks guys
TheMaryCTheMaryC

Hello... I found your post and it's exactly what I'm trying too do..... I want to copy an opportunity if the stage = posted and copy the products, too.  However, when I copy your code, I get an error "expected ';'"..... which I could say I knew what I was doing...but... we are just now reviewing the software and thinking of switching... anyway, any help would be greatly appreciated.

 

Thanks

 

NikiVNikiV

I would recommend doing this cloning in a trigger on the Opportunity.  If the Stage changes to "Posted" then have the trigger clone the Opportunity, clone any Products and save the whole thing.

 

Before you switch to another software, let me know if I can help!  SF.com can do this type of functionality with a little coding help.

 

MattMMattM

I'm attempting to do the same; have you been successful in doing this?  It would be great if you could share.  Cheers

londonembryolondonembryo

Hi, I'm new to SF and not a coder at all - but wondered if you may be able to help please.

 

I want to Clone a Custom Object w/wo a related object.  Is this possible? If so, please can you advise on how?