Showing posts with label Hyperion. Show all posts
Showing posts with label Hyperion. Show all posts

Tuesday, 2 July 2019

KScope19 – Deep-Dive into Data Integration



There were a lot of big announcements about the future direction data management is taking, and except for the proposed loss of our favourite FDMEE fish, they were all absolutely fantastic, and there is so much to be excited about. I’m going to give my views on the biggest announcements and the direction Data Integration is taking, and I’ll be getting some tutorials together once these features are available. But first:

Jargon Buster

  • FDMEE – on-premise Financial Data Management Extended Edition, amazing ETL tool for mappings, data import and export.
  • Data Management – the cloud version of FDMEE, built into PBCS etc
  • Data Integration – the shiny, fishless facelift of Data Management

Data Integration

Be ready, the new world is coming, and eventually it will replace the Data Management we all know and love. Data Integration functions the same as Data Management in the background, but it’s been designed to be a lot more user friendly. For example, rather than creating a source, target, then location, then import format, then load rule you will in the future just create an integration which encompasses most of those steps in one place.

They’ve applied the same logic to the options, which currently are spread all over the place but will now be accessible in one window. There are also some great new features coming with the facelift, such as Target Expressions which will allow you to apply several mappings at the load stage, including some mappings that were much more complicated to perform before. Target Expressions are complicated enough to deserve their own tutorial blog, so I’ll dive into those later, but another great feature is an official processing order for data maps, so no more alphabetical processing of data maps, you can get a like mapping to process first and then have explicit maps after if you want. This is a big Quality-Of-Life (QOL) update for admins and really shows Oracle are listening to feedback when it comes to data integrations.

You can also choose to skip the workbench stage, which can massively speed up integrations for day-to-day running if drill-through isn’t required, although you can then switch it back on and re-run an integration to troubleshoot any weirdness. I can see customers using this feature a lot. This is coming in version 19.05 for cloud.

You can start using Data Integration right now in PBCS, although full parity with Data Management doesn’t exist yet. As a result, you can create an integration in Data Integration and then jump into the more familiar Data Management interface to see how it all works in the background, and you can run an integration in either interface with no issues.

Data Export Updates

A recent highlight update for Data Management was the massive upgrade to flat file exports, which has given us several great options. These include:

  • Import a file template to create a flat file export
  • Include/Exclude the file header
  • Sort the data in a file export
  • Attributes can be exported into flat files
  • Easy reordering of output columns
  • Pivot specific dimensions into the columns
  • Choosing the accumulate (aggregate) data or not based on preference
  • Changing the data file parameter (we love a | in our csv files)
John Goodwin has blogged about it, so you know it’s great (check that out here) and there’s no point covering the same ground, so let’s move on!

Future Integrations to follow NetSuite to PBCS model

For those that haven’t read me gushing about the NetSuite integration, check my tutorial out here, but Mike Casey has confirmed that future direct integrations are planned to follow the NetSuite model. This means that they will support designing a query in the source system, pulling that specific query over to Data Management and mapping that query individually from other queries. This is AMAZING for importing metadata vs importing data which usually need completely different queries, all in the cloud, all on demand, all SIMPLY DELIGHTFUL

On-Premises Agent

The new on-premises agent will allow direct connections to on-premises systems, with a variety of configurable options to ensure all system admins can get on board with it. It will offer synchronous mode which is tougher to set up and requires more IT involvement but is constantly listening for requests, or asynchronous mode which can be run on a schedule and will execute any queued requests when it’s run on the server-side. Asynchronous doesn’t need a network port or any additional network infrastructure than EPM Automate needs now, so it will be less of a headache to set up.

Direct connections to on-prem databases from the cloud have been a massive request for a long time and it’s going to be a game-changer when this delightful tool comes out. It sounds seriously powerful!

Other Roadmap

Below is the roadmap which was shown at KScope19, under the usual Oracle Safe Harbour statement, so this represents their planned direction but no official commitment to release this stuff. Regardless, there’s plenty to keep guys like me excited and busy in here!


There was so much new and exciting content in the Data Management roadmap, that I haven’t even got around to discussing the direct HCM Cloud integration, including write-back, or the fact that data integration has been upgraded to allow a 5 million row limit!

Expect plenty of blogs giving blow-by-blow walkthroughs of the above once they’re released, but until next time, adios!

Mike

Wednesday, 14 November 2018

PBCS Cheap Tricks – Dealing with Dates and Depreciation.


Dates. They’ve been the bane of many a Hyperion Administrator’s life for about 20 years now and this is mostly due to the inconsistent and unfriendly business rule formulae surrounding them. The difficulties of dealing with dates makes calculating something like depreciation or amortisation very awkward, particularly when the same calculation is a dream to calculate in Excel.
As an example, let’s look at a lease with the following characteristics (you’ll need to calculate this for all leases in IFRS16 going forward so we may as well start now):

Lease Start Date: 1st January 2019
Lease End Date: 31st December 2028
Annual Rent: £10,000

For Depreciation, that's all we really need. We'll make some broad-brush assumptions that it will depreciate in every period that the start date falls in, starting from 01/2019 and will reach a £0 asset value in 12/2028. This gives it a life of 10 years x 12 months = 120 months. Because we are simplifying and not considering the present value of the rental payments, we assume the Initial Asset Value is 10 x £10,000 = £100,000

(FYI - for IFRS16 you'll also need an interest rate and I'll explore how you can achieve that in Hyperion Planning or PBCS in future blogs - the maths is really neat)

For now, all that means is we need to stick a depreciation amount of -£833.33 into every month between the start and end date and we will achieve our simple goal. So how do we calculate the correct dates in PBCS and match up the months we want to the life of the lease?

The answer is to define two accounts, Period Start Date and Period End Date which will both be Date type members. We will populate these members with the start and end date of each period and use them as reference points for our calculations. Seems too simple to be true right? If it's simple and it works, don't mess with it.

However, manually keying in the date is rather inelegant and frankly I'm disappointed in myself that for a while that's exactly what I did; until my colleague Alin came up with a brilliant solution. The key starting point is recognising how Hyperion loads in dates. They are loaded in the format YYYYMMDD which the clever of you will notice is an 8-digit number. You'll also be aware through a strong primary school education that months always have a consistent number of days (except February but we'll come to that). Therefore, it stands to reason that we can calculate the YYYYMMDD format number for any date.

The logic starts by defining a variable, that I usually define as &IFRS16_FIRST_CALENDAR_YEAR and set it to, for example, 2018. That is the number 2018, not the member FY18. I'll usually also have a sister variable &IFRS16_FIRST_YEAR with the value "FY18". You can work the calculation with any starting point but if you make it match your Year substitution variable then it's simpler to maintain.

We also need to define a Year Number, which we will set to 0 for the &IFRS16_FIRST_YEAR and increment by 1 every following year. For simplicity of calculation I just evaluated this in BegBalance but for optimal calculation speed you may want to put it in every period.

/*Initialise the Year Number in the IFRS16 FIRST YEAR member */
       FIX(&IFRS16_FIRST_YEAR,"BegBalance")
        "Year Number"(
        @CREATEBLOCK("Working");
       "Working" = 0;
        )
    ENDFIX

 /* Run a prior function to roll the year number forward. */
   FIX(@RSIBLINGS(&IFRS16_FIRST_YEAR),"Working","BegBalance")
       "Year Number"(
              @PRIOR("Year Number"->"BegBalance",1,@DESCENDANTS("All Years"))+1;
       )
   ENDFIX


We then use the following business rule to calculate the Period Start Date for January:

FIX ("Period Start Date")
/*For this installation, Jan FY18 = Jan-18 so we take &IFRS16_FIRST_CALENDAR_YEAR (2018) + Year Number (0) to get 2018, multiply it by 10000 to get 20180000 and add 101 to get 20180101 which is 1st January 2018. */
/*The next year, we will get &IFRS16_FIRST_CALENDAR_YEAR (2018) + Year Number (1) to get 2019, multiply it by 10000 to get 20190000 and add 101 to get 20190101 which is 1st January 2019. */
       Jan (
       (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 101;
        )
ENDFIX
/*Similarly, we take &IFRS16_FIRST_CALENDAR_YEAR (2018) + Year Number (0) to get 2018, multiply it by 10000 to get 20180000 and add 131 to get 20180131 which is 31st January 2018. */
FIX ("Period End Date")
       Jan (
       (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 131;
       )
ENDFIX

This approach works in the same way for all months except for Period End Date of February, which as we know differs on a leap year. Fortunately, Oracle have done us a solid with the @CalcMgrIsLeapYear function.

Feb (
      IF (@CalcMgrIsLeapYear((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 228))
               (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 229;
        ELSE
              (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 228;
        ENDIF
)                                             
You can, of course, bring all the start dates together into one member formula and do the same for each of the end dates, and since it's fairly trivial to follow the logic I will do you all a solid and present the full code below:

FIX ("Period Start Date")
        Jan ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 101;)
        Feb ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 201;)
        Mar ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 301;)
        Apr ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 401;)
        May ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 501;)
        Jun ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 601;)
        Jul ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 701;)
        Aug ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 801;)
        Sep ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 901;)
        Oct ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1001;)
        Nov ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1101;)
        Dec ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1201;)
ENDFIX

FIX ("Period End Date")
        Jan ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 131;)
        Feb (IF (@CalcMgrIsLeapYear((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 228))
                (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 229;
            ELSE
                (&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 228;
            ENDIF;)
        Mar ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 331;)
        Apr ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 430;)
        May ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 531;)
        Jun ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 630;)
        Jul ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 731;)
        Aug ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 831;)
        Sep ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 930;)
        Oct ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1031;)
        Nov ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1130;)
        Dec ((&IFRS16_FIRST_CALENDAR_YEAR + "Year Number"->"BegBalance") * 10000 + 1231;)  
ENDFIX

This generates the start and end dates for you for as many years as you have in the model:


Back to the point of the post, which was simple depreciation. Now that we have these weapons in our arsenal, we can calculate depreciation with ease. Simply load the lease start date, lease end date and asset value using your preferred method, and you can simply use the > and < operators to compare dates. For example:

IF("Lease Start Date"->"BegBalance" >= "Period Start Date" AND "Lease Start Date
"->"BegBalance" <= "Period End Date") - will return Jan-19 only
IF("Lease End Date"->"BegBalance" >= "Period Start Date" AND "Lease End Date"->"BegBalance" <= "Period End Date") - will return Dec-28 only
IF("Lease End Date"->"BegBalance" >= "Period Start Date" AND "Lease Start Date"->"BegBalance" <= "Period End Date") - will return Jan-19 to Dec-28 inclusive
IF("Lease End Date"->"BegBalance" > "Period End Date" AND "Lease Start Date"->"BegBalance" < "Period Start Date") - will return Jan-19 to Dec-28 exclusive

You can have a lot of fun with these comparators, because by using the Jan-19 to Dec-28 inclusive option, your rule has identified all the months that the depreciation calculation should place data into.

For a more complex solution you'll also need to calculate the Lease Life Remaining. This corresponds to the number of months remaining from the current date.

FIX (&IFRS16_CURRENT_YEAR, "BegBalance")
"Lease_Life_Remaining"(
/*If we don't have a Lease End Date then we will need to set this to missing*/
IF("Lease End Date" <> #Missing)
/*Here we use @CalcMgrDateDiff to find the number of months between the period end date and the lease end date. If this is less than the total lease life, we use this as the remaining life*/
       IF (@CalcMgrDateDiff("Period End Date"->&IFRS16_CURRENT_MONTH,"Lease End Date","month") < @CalcMgrDateDiff("Lease Start Date","Lease End Date","month"))
/*This evaluates as true in the situation where a lease started prior to our first period of interest, so depreciation must be applied retrospectively taking into account the depreciation that already happened*/
       @CalcMgrDateDiff("Period End Date"->&IFRS16_CURRENT_MONTH,"Lease End Date","month");
      ELSE
/*Otherwise, we use the Lease Life (in our example 119 months will be calculated by the formula.)*/
      @CalcMgrDateDiff("Lease Start Date","Lease End Date","month");
       ENDIF
ELSE
#Missing;
ENDIF
)
ENDFIX

So, at this point, we have the months that depreciation should be calculated in, the total asset value to depreciate, and the lease life remaining. Therefore, we simply need to place the depreciation in the correct periods.
We need to add 1 to our Lease Life Remaining to account for the fact that our model depreciates in the first month too - this can be easily configured if you prefer not to do this. The Initial Asset Value was simply the payments multiplied by the years.

"Depreciation"(
IF "Period End Date" >= "Commencement Date"->"BegBalance" AND "Period Start Date" <= "Termination Date"->"BegBalance)
(Initial Asset Value" -> "YearTotal" -> "All Years") / - ("Lease_Life_Remaining" -> &IFRS16_CURRENT_YEAR -> "BegBalance" + 1);
ENDIF
)

I've used a simplified version of our custom built IFRS16 model (using an interest % of 0) to show you how this will appear in PBCS.

If you want to learn more about our IFRS16 model in PBCS or on-premise Hyperion Planning, I’ll be posting more in-depth blogs on the calculations for some of the interesting parts including the present value, calculating the liability and visualising the different possible effects of interest rates, all through using the power of Essbase.

As always, leave a comment below if this helped you at all.