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
RVJRVJ 

Trigger Help - Copy ConvertCurrency (Amount) to a custom # field

Hi - I am trying to copy the converted currency amount on opportunity to a custom field.  My purpose for doing this is to use the custom field in another trigger to roll up information to the Top Level Account - I can't use SF roll up features because we use multi-currency and dated exchange rates - at this point I am not concerned about the dated exchange rates - but as I say it limits what I can in SF.  

 

I am very new to Apex Code but have given it a bash, I have the following code - which does work - however I have it on before update and therefore it is taking the amount value from the opportunity - I really need to either change this to an after update trigger or modify my code to look at the new value.  I get an error when I change to after update saying that the record is read only.  If someone is able to point me in the right direction, it would be much appreciated.  Thank you.

 

trigger CopyConvertedValue on Opportunity (before update) {

 

Integer i = 0;
Opportunity Oppy = Trigger.new[i];

String intTest = Trigger.new[i].ID;

//Step 2. Create a list of Opps
List<Opportunity> Oppys = [Select convertCurrency(Amount)From Opportunity where ID =: intTest];

for (Opportunity Opp : oppys)


//Step 3. Update Oppy
Trigger.new[i].Converted_Value__c = Trigger.new[i].Amount;
}

cloudmaniacloudmania

You can not use current record in trigger in case of "After insert".

 

Try to query for the records in Trigger and update again.

RVJRVJ

Thanks for the reply erkan, sorry - I am trying all kinds of different ways to grab the data from the trigger - I take it doing a List isn't the right way?

dmchengdmcheng

First, remember that triggers run in system mode, so I think the convertCurrency function will use the default currency of your Salesforce organization. Make sure this is what you want for your calculations.

 

Second - you can write an afterupdate trigger, but you to include code in it to avoid an infinite loop since you will be updating the opps again to fill in the custom field.

trigger CopyConvertedValue on Opportunity (after update) {
	Set<Id> oppIDs = new Set<Id>();

	//Identify the records where amount has changed.
	for(Opportunity opp : Trigger.new) {
		if(opp.Amount != Trigger.oldMap.get(opp.Id).Amount) {
			oppIDs.add(opp.Id);
		}
	}
	
	//This avoids infinite loop when opps are updated later.
	if(!oppIDs.isEmpty()) {
		Opportunity[] opps = [select convertCurrency(Amount) from Opportunity where Id in :oppIDs];
		for(Opportunity opp : opps) {
			opp.Converted_Amount__c = opp.Amount;
		}
		update opps;
	}
}

 

Don Barnes 5Don Barnes 5

I find that the above elegant code from dmcheng does not work because if modifies the value of Amount in the for loop at line 14.  This will make the trigger fail in a recursive way.  To make this tigger work add the following line in the same for loop after line 15.

opp.Amount = Trigger.newMap.get(opp.id).Amount;

This line makes sure the Amount field is not recurively modified until the trigger fails.  Here is the modified code:
 
trigger CopyConvertedValue on Opportunity (after update) {
    Set<Id> oppIDs = new Set<Id>();

    //Identify the records where amount has changed.
    for(Opportunity opp : Trigger.new) {
        if(opp.Amount != Trigger.oldMap.get(opp.Id).Amount) {
            oppIDs.add(opp.Id);
        }
    }
    
    //This avoids infinite loop when opps are updated later.
    if(!oppIDs.isEmpty()) {
        Opportunity[] opps = [select convertCurrency(Amount) from Opportunity where Id in :oppIDs];
        for(Opportunity opp : opps) {
            opp.Converted_Amount__c = opp.Amount;
            opp.Amount = Trigger.newMap.get(opp.id).Amount;
        }
        update opps;
    }
}