+ Start a Discussion
Cdolan04Cdolan04 

Apex Trigger to duplicate Custom Object fields to another Custom Object

Force community, 

 

I'm new to writing Apex triggers, and wanted to get some feedback on my issue. I currently have two Custom Objects - lets call those CO1 and CO2.

 

CO1 records are created as children of Opportunities, and contain about 20 fields. When my company signs on a client, we change a field called 'Type' on the Account object to 'Customer' instead of 'Prospect'. When this happens, I'd like to have an Apex Trigger create a new CO2 record, and copy all the data from existing CO1 records (which are, again, children of the opportunity), to CO2 records, which are merely related to Accounts.

 

I'm pretty new to this, but my two biggest questions are these: Do I have to compare a map to notice if the Type = Customer? And how exactly do I navigate related objects to find the correct CO1 record to copy? 

 

Thanks, any help is apprecaited! 

 

kerwintangkerwintang

Since an Account has many Opportunities, do you want to get all CO1 objects of all Opportunities of that Account?

 

If yes, i think you would have to create a trigger in Account that does the following:

1. Check if Account Type = Customer and previous Type != Customer.

2. Get all CO1s of opportunities of that Account via SOQL : [select Id,Name, .... from CO1 where Opportunity.Account = {account id here}]

3. Loop through the retrieved list and create CO2 record for each iteration.

 

Hope this helps!

Cdolan04Cdolan04

Kerwintang, 

 

You bring up a valid point regarding the multiple Opportunities per account, and that is important to consider, but my company generally does just 1 Opportunity per account. 

 

I've been looking into this for a couple of days, and I'm not sure I'll be able to fully impliment this by myself, but it is certianly fun to play with. Even if I end up hiring a developer, this has been helpful in terms of making a 'roadmap' for the trigger.

 

The last part of the trigger that I don't quite fully understand is how to relate CO2 records back to the Account linked to CO1 (CO1's have parent Opportunities, which then have Parent Accounts) 

 

Could you give me an information related to that?

 

Thanks for your help!

 

Edit - At first I'd assume it requires doing Step 2 from your post in reverse, but there is no Parent/Child relationship between CO2's and an Opportunity / Account

kerwintangkerwintang

Regardless if you have 1 or multiple Opportunities per Account, the solution should still be the same:

 

List<CO1> co1Records =  [select Id,Name, .... from CO1 where Opportunity.Account = {account id here}];

 

Then loop through the list :

 

for(CO1 co1:co1Records){

CO2 co2 = new CO2();

//copy co1 details to co2

co2.field1 = co1.field1;

co2.field2 = co1.field2;

...

//to link the co2 record to the account:

co2.Account__c = co1.Account__c;

insert co2;

}

 

The above code is just the idea, feel free to modify it to align with your requirement :D

 

tomcollinstomcollins

Is it possible to just "insert co1.clone()" inside the loop?

 

I haven't used the clone() method, but I'd think that's the best way to duplicate a custom object.

Cdolan04Cdolan04

As i understand it, clone would indicate to duplicate the fields in CO1, and would not really help to push those to CO2. The field names/labels may be similar, but they are different in terms of pointing the field.

 

Essentially, you still need to map the 'road' between fields in CO1, to their respective fields in CO2.

 

I'd happily be overrulled if someoone with more knowledge wants to get involed.

 

 

kerwintangkerwintang

I agree with Cdolan04 on that one.

 

You may need to create the CO2 object and manually assign the field values from the CO1 object.

 

An alternative would be to create a CO1 look-up field in CO2. In the trigger, when you create the CO2 data, simply assign CO2.CO1 = CO1. In this case, you can access the CO1 values by calling CO2.CO1.fieldName. The downside to this is the CO2 record is attached to CO1 and whatever changes happen to CO1 will affect the CO2 record as well.

tomcollinstomcollins

Have either of you actually read what the clone() method does?

 

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_methods_system_sobject.htm

 

Creates a copy of the sObject record.

 

The optional opt_preserve_id argument determines whether the ID of the original object is preserved or cleared in the duplicate. If set to

true, the ID is copied to the duplicate. The default isfalse, that is, the ID is cleared.

Note

For Apex saved using Salesforce.comAPI version 22.0 or earlier, the default value for the opt_preserve_idargument istrue, that is, the ID is preserved.
The optional opt_IsDeepCloneargument determines whether the method creates a full copy of the sObject field, or just a reference:
  • If set totrue, the method creates a full copy of the sObject. All fields on the sObject are duplicated in memory, including relationship fields. Consequently, if you make changes to a field on the cloned sObject, the original sObject is not affected.
  • If set tofalse, the method performs a shallow copy of the sObject fields. All copied relationship fields reference the original sObjects. Consequently, if you make changes to a relationship field on the cloned sObject, the corresponding field on the original sObject is also affected, and vice-versa. The default isfalse.

The optional opt_preserve_readonly_timestampsargument determines whether the read-only timestamp fields are preserved or cleared in the duplicate. If set totrue, the read-only fields CreatedById, CreatedDate, LastModifiedById, and LastModifiedDateare copied to the duplicate. The default isfalse, that is, the values are cleared.

The optional opt_preserve_autonumberargument determines whether auto number fields of the original object are preserved or cleared in the duplicate. If set totrue, auto number fields are copied to the cloned object. The default is false, that is, auto number fields are cleared.

 

 

 

How is this not what the original poster is looking for?!

tomcollinstomcollins

Ah, I see the difference now.  CO2 is a different object with similar fields to CO1.

 

Ignore my clone() post...

Cdolan04Cdolan04

Kerwintang,

 

I think you are onto something with the last post, but my problem is this - CO1's in my org are used to represent client's data -before- they started service with us. CO2's represent their service with us today, and since our business is run to save our customers money, that margin is the most important metric that we can show. By the way, if anyone is reading this in the future and does not need the fields to be different, a lookup relationship between the fields could work, and you could probably do it through a workflow, and perhaps with field updates, and avoid coding a trigger all together.

 

I still havn't had the time to learn the code for the trigger yet - but when I get the chance to make it work I'll report back and post the code.

kerwintangkerwintang

Ok. If that's the case then i think you can reuse some part of this code:

 

List<CO1> co1Records =  [select Id,Name, .... from CO1 where Opportunity.Account = {account id here}];

 

for(CO1 co1:co1Records){

CO2 co2 = new CO2();

//copy co1 details to co2

co2.field1 = co1.field1;

co2.field2 = co1.field2;

...

//to link the co2 record to the account:

co2.Account__c = co1.Account__c;

insert co2;

}