8

Historically it's been possible to determine if advanced currency management is enabled by using:

Schema.getGlobalDescribe().containsKey('DatedConversionRate');

as this object is only available on orgs with this feature enabled.

See How to identify Advanced currency is enabled in apex class?

Also, per the docs:

This object is for multicurrency organizations with advanced currency management enabled. Use this object to define the exchange rates your organization uses for a date range. This object is not available in single-currency organizations, nor is it available if the organization does not have advanced currency management enabled.

On two orgs today I found that the DatedConversionRate object is showing up even if advanced currency management is disabled (I don't know if this only happens on orgs where advanced currency management has previously been enabled).

What I'd like to know is:

  1. Does anyone else reproduce this issue?
  2. Can anyone test this on a multi currency org that has never had advanced currency management enabled?
  3. Does anyone know of an alternate way to determine in Apex if advanced currency management is enabled?
  4. Am I missing anything obvious here?

Here's a test class you can use to detect the presence of DatedConversionRate objects. I have tested on APIs back to 32, so it does not seem to be a versioned change.

@istest
public class test1 {
    @istest
    public static void test1()
    {
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        system.debug(gd.containsKey('DatedConversionRate'));
    }
}
kibitzer
  • 3,434
  • 19
  • 25
  • To add clarification to #2: "Can anyone test this on a multi currency org that has never had advanced currency management enabled?" This means an org that does have multi-currency turned on (a feature that is not enabled by default on a new org), but has never had the advanced currency management (dated currency rates) turned on. – kibitzer Apr 22 '16 at 18:22
  • I just tried the sample code as anonymous apex on na2. The describe came back for 'DatedConversionRate'. Confirmed that "Advanced Currency Management is not enabled" under setup. I don't think it has ever been on in this Org. I can also do a Select Id from DatedConversionRate. No rows come back, but it appears to be a valid SOQL query, – Daniel Ballinger Apr 23 '16 at 08:08
  • If, indeed, that org has never had Advanced Currency Management enabled, then this is definitely a change in behavior. I do have an org where I can read DatedConversionRate data even with Advanced Currency Management off - my suspicion is that this is an org that previously had it enabled. In any case, as I'm seeing it right now - there has been a change in behavior that renders the previous design pattern ineffective, that apps using that design pattern may be returning incorrect results with nobody the wiser, and that there is no reliable way to determine if this feature is enabled. – kibitzer Apr 24 '16 at 00:03
  • If a SOQL query against DatedConversionRate returned no records, would it be equivalent to the feature being disabled? Not as efficient as the describe call. Maybe as a backup option? – Daniel Ballinger Apr 24 '16 at 05:21
  • I'd say that would be a workable solution. I would hope that most people doing their own conversion would already have that form of backup in places (I know that I do). I don't think the efficiency is a huge concern - it's +1 query, and I expect anyone doing these kinds of operations is caching the data for the duration of the execution context anyway. – kibitzer Apr 25 '16 at 16:30
  • https://success.salesforce.com/issues_view?id=a1p3A0000017yARQAY - Still doesn't acknowledge that it used to work per the docs, so this is a breaking change. – kibitzer May 04 '16 at 02:50

1 Answers1

3

Describe info gets cached when it's first requested. Have you perhaps added some describe logic to your code? Can you reproduce this in a vanilla org? I just ran that code snippet as the test class provided and via execute anonymous in a Spring '16 and Summer '16 org and got false each time.

Josh Kaplan
  • 752
  • 6
  • 8
  • 2
    It's not just describe info - in that I can also query on the object (SOQL query should fail with an error), still this is possible - but if so it does represent a change in behavior. Did you test on a multi-currency org? Remember - plan vanilla orgs do not have multi-currency enabled, and those will return false - that still works. If you did see it on a multi-currency org, could you turn on advanced currency management, and then turn it off again and see if it returns true or false? That is a possible scenario - that it only occurs on orgs that previously had advanced currency management. – kibitzer Apr 22 '16 at 18:19
  • You can get the same behavior without doing a describe, if you load an object of a certain type in one API version before accessing it in a different version. That said, I am guessing that's not your issue. Since these orgs had multi-currency turned on, it's possible that the schema needs to continue to reflect the existence of this object type to retain data consistency. I'm not 100% certain of that, but it seems a probable explanation. I'm not sure how this is problematic, though...if you see the object type but return no rows, isn't that the same as not finding it in the describe? – Josh Kaplan Apr 23 '16 at 20:27
  • Ah, but we see the object type AND we get rows returned when we do a query! Also, the behavior change doesn't seem to be versioned - at least, I get the same thing for testing on API 32 and 36. I'm certain that in the past we could reliably use the existence of the DatedConversionRate object to determine if advanced currency management is turned on or not on multicurrency ors. With this change in behavior, there is no way to do so. Worse, any apps relying on that design pattern are now potentially returning incorrect results - but nobody knows it. This seems to me a pretty big problem. – kibitzer Apr 23 '16 at 23:58
  • Why do you see this as a change in behavior? When did you begin to see the behavior? And if there are data rows for dated currency, what is the expected behavior? I don't know that area, so I don't know the expected behavior when an org goes from dated exchange rates to no-more-dated-exchange-rates. I can see the answer being that those rates are still in force, because otherwise records that have been calculated in certain ways would suddenly have new values. That could potentially cause serious havoc, possibly more than to your innovative hack which guesses at whether the feature is active. – Josh Kaplan Apr 25 '16 at 17:06
  • Well, in the past you could reliably use the presence of DatedConversionRate objects to determine if advance currency management was enabled - it was a lot like a RecordTypeID - no record types, no field. That was how you'd know if advanced currency management was enabled. When disabled, one would expect that object to vanish, or at the very least, for no records to be returned. You must be doing something like that internally, as your fields work correctly - when currency management is disabled, the DatedConversionRate data is ignored. But if Apex is still seeing those records, it has ... – kibitzer Apr 25 '16 at 17:12
  • .. no way to know how to correctly calculate the correct exchange rate. Any existing code that uses either the describe design pattern, or a return of no DatedConversionRate records to know to look at the standard conversion values, is going to fail - as it's seeing data that's no longer valid. Hence my view that something has changed and is causing applications to silently return incorrect data - which is in my mind very problematic. Unfortunately, I don't know when this changed - as the data error can be very small. We only found it because one org had an inverted value.. – kibitzer Apr 25 '16 at 17:13
  • ... in a DatedConversionRate object, and we couldn't figure out why that data even existed or was being looked at in an org that had advanced currency management disabled! So now we're sort of stuck, in that there is no way to determine correctly which conversion data to use! – kibitzer Apr 25 '16 at 17:16
  • One more thing to stress - you say " I can see the answer being that those rates are still in force, because otherwise records that have been calculated in certain ways would suddenly have new values." - But that's how Salesforce handles it internally, as your fields are definitely not using the DatedConversionRate data in this case. We know this because the way we found the problem was in comparing your conversion results with ours. – kibitzer Apr 25 '16 at 17:20