I have written an Apex Trigger to perform the rollup summary(sum ) operation..In the image "Total order Item value" field will be populated using trigger. And "Total Order Items" populates the value based on rollup summary.
The problem here is. under Total order Item Value instead of considering user define currency value, it is taking default company value which show with arrow.
Total Order Item Value will depend on (Quantity * Sell price)which returns value in usd. I want the same USD value under this field instead of converted.
Let me know thoughts.
Here is the code:
Apex class:
public class RollUpSummaryUtility {
//the following class will be used to house the field names
//and desired operations
public class fieldDefinition {
public String operation {get;set;}
public String childField {get;set;}
public String parentField {get;set;}
public fieldDefinition (String o, String c, String p) {
operation = o;
childField = c;
parentField = p;
}
}
public static void rollUpTrigger(list<fieldDefinition> fieldDefinitions,
list<sObject> records, String childObject, String childParentLookupField,
String parentObject, String queryFilter) {
//Limit the size of list by using Sets which do not contain duplicate
//elements prevents hitting governor limits
set<Id> parentIds = new set<Id>();
for(sObject s : records) {
parentIds.add((Id)s.get(childParentLookupField));
}
//populate query text strings to be used in child aggregrator and
//parent value assignment
String fieldsToAggregate = '';
String parentFields = '';
for(fieldDefinition d : fieldDefinitions) {
fieldsToAggregate += d.operation + '(' + d.childField + ') ' +
', ';
parentFields += d.parentField + ', ';
}
//Using dynamic SOQL with aggergate results to populate parentValueMap
String aggregateQuery = 'Select ' + fieldsToAggregate +
childParentLookupField + ' from ' + childObject + ' where ' +
childParentLookupField + ' IN :parentIds ' + queryFilter + ' ' +
' group by ' + childParentLookupField;
//Map will contain one parent record Id per one aggregate object
map<Id, AggregateResult> parentValueMap =
new map <Id, AggregateResult>();
for(AggregateResult q : Database.query(aggregateQuery)){
parentValueMap.put((Id)q.get(childParentLookupField), q);
}
//list of parent object records to update
list<sObject> parentsToUpdate = new list<sObject>();
String parentQuery = 'select ' + parentFields + ' Id ' +
' from ' + parentObject + ' where Id IN :parentIds';
//for each affected parent object, retrieve aggregate results and
//for each field definition add aggregate value to parent field
for(sObject s : Database.query(parentQuery)) {
Integer row = 0; //row counter reset for every parent record
for(fieldDefinition d : fieldDefinitions) {
String field = 'expr' + row.format();
AggregateResult r = parentValueMap.get(s.Id);
//r will be null if no records exist
//(e.g. last record deleted)
if(r != null) {
Decimal value = ((Decimal)r.get(field) == null ) ? 0 :
(Decimal)r.get(field);
s.put(d.parentField, value);
} else {
s.put(d.parentField, 0);
}
row += 1; //plus 1 for every field definition after first
}
parentsToUpdate.add(s);
}
//if parent records exist, perform update of all parent records
//with a single DML statement
if(parentsToUpdate.Size() > 0) {
update parentsToUpdate;
}
}
}
Trigger:
trigger GT_TotalOrderItem on OSF_Order_Items__c (after delete, after insert,
after update, after undelete) {
if(trigger.isInsert || trigger.isUpdate || trigger.isUnDelete){
list<RollUpSummaryUtility.fieldDefinition> fieldDefinitions =
new list<RollUpSummaryUtility.fieldDefinition> {
new RollUpSummaryUtility.fieldDefinition('SUM', 'Total_Selling_Price__c',
'Test_Total_Order_Item__c')
};
RollUpSummaryUtility.rollUpTrigger(fieldDefinitions, trigger.new,
'OSF_Order_Items__c', 'Opportunity__c', 'Opportunity', '');
}
if(trigger.isDelete){
list<RollUpSummaryUtility.fieldDefinition> fieldDefinitions =
new list<RollUpSummaryUtility.fieldDefinition> {
new RollUpSummaryUtility.fieldDefinition('SUM', 'Total_Selling_Price__c','Test_Total_Order_Item__c')
};
RollUpSummaryUtility.rollUpTrigger(fieldDefinitions, trigger.old,
'OSF_Order_Items__c', 'Opportunity__c', 'Opportunity', '');
}
}
Best Answer
I don't see in your trigger or in your class where you're obtaining the
currency
of the order or thecurrent exchange rate
used by your company to calculate currency exchange.Companies can do that differently through salesforce, depending on how they set-up multi-currency exchange (e.g. some do it quarterly). You'll need to add those factors into your class and either pass them to it through your trigger or have the class query the values.
EDIT
You'll want to look at these two links: Implications of Enabling Multiple Currencies and About Advanced Currency Management. I think they'll help provide more insight into the issues you're dealing with.
Edit2
Since you're using custom fields I recommend you review them to make certain they reflect the same type of values. There's often an
Internal cost
of some kind as in cost to make or purchase the item for your org, aDistributor cost
orPartner cost
and aRetail Cost
. In my experience, depending on your org and how they've set things up, Opportunity can often reflect any one or a combination of these numbers, particularly when it comes to who they're being displayed to.These decisions have other implications on
VisualForce page bindings
which don't affect your particular situation. Roll-up summary fields between two advanced currency management objects are also impacted whenAdvanced Currency Management
is implemented. For example, roll-up summary fields are supported from an opportunity line object to its opportunity object, because both are advanced currency management enabled. However, if you enable advanced currency management, you can’t create roll-up summary fields that calculate currency on the opportunity object rolling up to the account object, and you can’t filter on the opportunity currency field on the account object. In your particular situation, since we're talking about an opportunity and it's children, plus with this being a trigger, there should be no impact.Finally, a
User's Settings
determines whichcurrency
the Opportunity is displayed in. Your Org'sCurrency Management Settings
determines how exchange rates are managed. IfAdvanced Currency Management
is Enabled, normally Dated Exchange Rates are used for opportunities, opportunity products, opportunity product schedules, campaign opportunity fields, opportunity splits, and reports related to these objects and fields. Otherwise, Static conversion rates are used.Based on the above, this tells me your problem is most likely either one of not having the correct fields you needed to perform your calculations (or to compare them to) or one of not having all the line items needed when performing your roll up calculations. Either that or there's a problem with your algorithm for calculating the roll-up summary value.
I hope you find this information useful to you in sorting your difficulties.