Hi all,
I had faced some issue finding the correct way to update the money type fields in Dynamics CRM and I write this post so that you do not have to face the same issue in your development journey. As you would know when we create a field in Dynamics CRM of the "Currency" type it creates internally another field with schema name ' "schema name of the original currency field"_base'. Basically in this _base field the currency value is stored in the base currency of the system and in the original field the value is stored in the user's chosen currency or organizational set currency. Hence, each record in Dynamics CRM has a Currency lookup field with schema name "transactioncurrency" to the transactioncurrency entity that contains the details of the currency when this record was created. Among other details this entity also contains the exchange rate between this currency and the base currency of the system.
So my requirement was to update the total fees field in opportunity when the "fees" field in one of the related Opportunity product entities was updated. Due to some security related requirement, we were not using roll-up field and needed to achieve the functionality using a plugin.
decimal totalDealProductFees = 0;
var dealProductsQuery = new QueryExpression("opportunityproduct");
dealProductsQuery.ColumnSet = new ColumnSet(new string[] { "contoso_fees_base" });
dealProductsQuery.Criteria.AddCondition("opportunityid", ConditionOperator.Equal, dealEntityRef.Id);
EntityCollection dealProductsQueryResults = orgService.RetrieveMultiple(dealProductsQuery);
if (dealProductsQueryResults != null && dealProductsQueryResults.Entities != null && dealProductsQueryResults.Entities.Count > 0)
{
tracingService.Trace("The number of deal product records obtained is: " + dealProductsQueryResults.Entities.Count);
foreach (var dealProduct in dealProductsQueryResults.Entities)
{
var feesDealProduct = dealProduct.GetAttributeValue<Money>("contoso_fees_base");
if (feesDealProduct != null)
{
totalDealProductFees += feesDealProduct .Value;
}
}
}
var exchangeRate = GetCurrencyExchangeRate(orgService, dealEntity.Id);
dealEntity["contoso_totalfees"] = new Money(totalDealProductFees * exchangeRate);
dealEntity["contoso_totalfees_base"] = new Money(totalDealProductFees);
orgService.Update(dealEntity);
private static decimal GetCurrencyExchangeRate(IOrganizationService service, Guid dealId)
{
Guid CurrencyId = Guid.Empty;
decimal oppExchangeRate = 0;
if (dealId != Guid.Empty)
{
Entity oppEntity = service.Retrieve("opportunity", dealId, new ColumnSet("transactioncurrencyid"));
CurrencyId = oppEntity.GetAttributeValue<EntityReference>("transactioncurrencyid").Id;
}
if (CurrencyId != Guid.Empty)
{
Entity currencyEntity = service.Retrieve("transactioncurrency", CurrencyId, new ColumnSet("exchangerate"));
oppExchangeRate = currencyEntity.GetAttributeValue<decimal>("exchangerate");
}
return oppExchangeRate;
}
The GetCurrencyExchangeRate method gets the currency exchange rate by obtaining the relevant fields from the opportunity entity and the transactioncurrency entities as discussed in the theory above.
As you will observe the currency fields are assigned their value by assigning to them a Money object, which has a constructor that takes a decimal value. We assign the actual computed value to the base field in the deal (opportunity) record and the value that is shown to the user is updated with the the actual value multiplied by the required exchange rate as obtained by the method discussed above.
Thus by following the above approach we can ensure that the currency values are in sync as required by the platform.
Hope this helps and feel free to leave your comments.
Thanks and Happy Dynamics!
I had faced some issue finding the correct way to update the money type fields in Dynamics CRM and I write this post so that you do not have to face the same issue in your development journey. As you would know when we create a field in Dynamics CRM of the "Currency" type it creates internally another field with schema name ' "schema name of the original currency field"_base'. Basically in this _base field the currency value is stored in the base currency of the system and in the original field the value is stored in the user's chosen currency or organizational set currency. Hence, each record in Dynamics CRM has a Currency lookup field with schema name "transactioncurrency" to the transactioncurrency entity that contains the details of the currency when this record was created. Among other details this entity also contains the exchange rate between this currency and the base currency of the system.
So my requirement was to update the total fees field in opportunity when the "fees" field in one of the related Opportunity product entities was updated. Due to some security related requirement, we were not using roll-up field and needed to achieve the functionality using a plugin.
decimal totalDealProductFees = 0;
var dealProductsQuery = new QueryExpression("opportunityproduct");
dealProductsQuery.ColumnSet = new ColumnSet(new string[] { "contoso_fees_base" });
dealProductsQuery.Criteria.AddCondition("opportunityid", ConditionOperator.Equal, dealEntityRef.Id);
EntityCollection dealProductsQueryResults = orgService.RetrieveMultiple(dealProductsQuery);
if (dealProductsQueryResults != null && dealProductsQueryResults.Entities != null && dealProductsQueryResults.Entities.Count > 0)
{
tracingService.Trace("The number of deal product records obtained is: " + dealProductsQueryResults.Entities.Count);
foreach (var dealProduct in dealProductsQueryResults.Entities)
{
var feesDealProduct = dealProduct.GetAttributeValue<Money>("contoso_fees_base");
if (feesDealProduct != null)
{
totalDealProductFees += feesDealProduct .Value;
}
}
}
var exchangeRate = GetCurrencyExchangeRate(orgService, dealEntity.Id);
dealEntity["contoso_totalfees"] = new Money(totalDealProductFees * exchangeRate);
dealEntity["contoso_totalfees_base"] = new Money(totalDealProductFees);
orgService.Update(dealEntity);
private static decimal GetCurrencyExchangeRate(IOrganizationService service, Guid dealId)
{
Guid CurrencyId = Guid.Empty;
decimal oppExchangeRate = 0;
if (dealId != Guid.Empty)
{
Entity oppEntity = service.Retrieve("opportunity", dealId, new ColumnSet("transactioncurrencyid"));
CurrencyId = oppEntity.GetAttributeValue<EntityReference>("transactioncurrencyid").Id;
}
if (CurrencyId != Guid.Empty)
{
Entity currencyEntity = service.Retrieve("transactioncurrency", CurrencyId, new ColumnSet("exchangerate"));
oppExchangeRate = currencyEntity.GetAttributeValue<decimal>("exchangerate");
}
return oppExchangeRate;
}
The GetCurrencyExchangeRate method gets the currency exchange rate by obtaining the relevant fields from the opportunity entity and the transactioncurrency entities as discussed in the theory above.
As you will observe the currency fields are assigned their value by assigning to them a Money object, which has a constructor that takes a decimal value. We assign the actual computed value to the base field in the deal (opportunity) record and the value that is shown to the user is updated with the the actual value multiplied by the required exchange rate as obtained by the method discussed above.
Thus by following the above approach we can ensure that the currency values are in sync as required by the platform.
Hope this helps and feel free to leave your comments.
Thanks and Happy Dynamics!
No comments:
Post a Comment