13

I just looked in the Salesforce.com documentation for a way to update currency rates using Apex, but I have a vague feeling that this is not possible using standard features. I noticed that a couple of packages on AppExchange are doing this for free, but I was looking to integrate our own module since we use a different rate provider. I guess that it is related to DatedConversionRate (detailed here)

What is the best way to achieve this? I guess it's doable using a workaround such as calling the Metadata API, but not sure how to implement it. Any sample/example?

Thanks!

3

2 Answers 2

31

The Metadata API does not give access to this information, this is used for org configuration such as custom objects and fields. CurrencyType and DatedConversionRate contain record level information. As per the documentation you linked to, you can use the SOAP API to insert and udpate records in these.

All standard and custom objects can also be accessed through the SOAP API.

Which I also assume would mean the REST API aswell and indeed it does...

Here is a working REST API insert via Apex for DatedConversionRate...

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v28.0/sobjects/DatedConversionRate/');
    req.setBody('{ "IsoCode" : "ADP", "ConversionRate" : 1.5, "StartDate" : "2013-06-26" }');
    req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setMethod('POST');
    HttpResponse res = h.send(req);

Here is a working REST API update via Apex for DatedConversionRate...

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v28.0/sobjects/DatedConversionRate/04wb0000000KzHlAAK?_HttpMethod=PATCH');
    req.setBody('{ "ConversionRate" : 2.5 }');
    req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setMethod('POST');
    HttpResponse res = h.send(req);

Note: Using setMethod('PATCH') gives an Apex error. The documentation for HttpRequest.setMethod does not list 'PATCH' as a method, though it says 'for example', so its unclear if its saying its not supported or the documentation author just missed it out.

Fortunately you can override the Http method as a URL parameter as described here.

If you use an HTTP library that doesn't allow overriding or setting an arbitrary HTTP method name, you can send a POST request and provide an override to the HTTP method via the query string parameter _HttpMethod. In the PATCH example, you can replace the PostMethod line with one that doesn't use override: PostMethod m = new PostMethod(url + "?_HttpMethod=PATCH");

7
  • 2
    This is brilliant! It never occurred to me that Apex could 'callout' to the SFDC cloud. Veils lifted from my eyes! This solves another problem I had of Apex provisioning Sobject SelfServiceUser, also not supported by Apex DML
    – cropredy
    Jun 27, 2013 at 1:19
  • Great, thanks for this response too Andrew! Is there a reason why Salesforce.com doesn't allow DML access to CurrencyType and other objects?
    – jpmonette
    Jun 27, 2013 at 14:21
  • 2
    I suspect its purely for internal historic architecture reasons, these objects predate even Apex! :) This answer gave me a few more challenges than the other, as all you get back is 'Bad Request' if you have say for example, forgot to enable Advanced Multi-Currency in your dev org! Doh! ;-) Jun 27, 2013 at 14:24
  • @jpmonette How did this work out for you? Did it get you going? Jul 25, 2013 at 11:23
  • 1
    Ah I see, shame, glad the answer I gave at least resolved part of you it for you though! Happy to help! :) Jul 26, 2013 at 22:35
2

Although this is a few years old it is still awesome and saved my bacon. Part of our solution needed to remove some Dated Conversion Rate records as well. Thought I'd just throw this up here for quick reference even though everyone could probably figure it out pretty quickly.

Here is a working REST API delete via Apex for DatedConversionRate...

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v28.0/sobjects/DatedConversionRate/04wb0000000KzHlAAK?_HttpMethod=DELETE');
req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
req.setHeader('Content-Type', 'application/json');
req.setMethod('POST');
HttpResponse res = h.send(req);
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .