Forum Discussion

MEverts's avatar
MEverts
Frequent Visitor
3 years ago
Solved

Employee Utilization Rate - Incorrect Roll-up to month level when calculating Expected Hours

Dear all,
I’m calculating employee utilization rates as the proportion of billable hours (actuals), divided by the Expected Hours (projected) minus Leave-hours (actuals):

[Billable_Hrs]/([Expected_Hrs] - Leave_Hrs) – between selected dates.


I need to ‘project/calculate’ the expected number of hours ([Sum_Expected_hrs] below) for multiple employees across different date-granularities (e.g. per department for a particular month), however, my current measure fails to roll-up the Expected Hrs correctly to a month- or year-level when selecting multiple-employees with overlapping Start- and Stop-dates. This makes any Utilization-% calculations incorrect for months where employees left the company.
I have:

  • A date-dim table ‘Calendar’ (with work-days)
  • An Employee-dim/fact table 'Direct Reports_Last_Active', which lists unique employee information, with their [start-date] & [stop-date], as well as their contracted hours per day [Hrs_per_day]. (Stop-date=Today() when currently employed).
  • A time-sheet-fact table ‘Timesheet_NB’ with actuals for Billable/Non-billable & Leave hours for all employees.

I try to summarize the situation in the table below:

 

 

Here is the syntax for my failing measure Sum_Expected_hrs:

 

Sum_Expected_hrs =
VAR CurrentStart =
    MIN ( 'Direct Reports_Last_Active'[Min_Start] )
VAR CurrentEnd =
    MAX ( 'Direct Reports_Last_Active'[Stop_date] )
VAR _CurrDate =
    CALCULATE (
        MAX ( 'Calendar'[date] ),
        FILTER ( 'Calendar', 'Calendar'[Date] >= CurrentStart ),
        FILTER ( 'Calendar', 'Calendar'[Date] <= CurrentEnd ),
        FILTER ( 'Calendar', 'Calendar'[WEEKDAY] = 1 )
    )
VAR _Count_Expected_Hrs =
    CALCULATE (
        SUM ( 'Direct Reports_Last_Active'[Hrs_per_day] ),
        FILTER (
            'Direct Reports_Last_Active',
            'Direct Reports_Last_Active'[Min_Start] <= _CurrDate
                && 'Direct Reports_Last_Active'[Stop_date] >= _CurrDate
        ) //      ,'Direct Reports_Last_Active'[Employee_ID]=xxxxx  // Filter to create [Empl_A] / [Empl_B]
    )
VAR Days_in_selection =
    CALCULATE (
        COUNTROWS ( 'Calendar' ),
        FILTER ( 'Calendar', 'Calendar'[Date] >= CurrentStart ),
        FILTER ( 'Calendar', 'Calendar'[Date] <= CurrentEnd ),
        FILTER ( 'Calendar', 'Calendar'[WEEKDAY] = 1 )
    )
VAR Sum_Expected_Hrs =
    CALCULATE (
        Days_in_selection * _Count_Expected_Hrs,
        FILTER ( 'Calendar', MIN ( 'Calendar'[Date] ) < 'Calendar'[Date] ),
        FILTER (
            'Calendar',
            'Calendar'[Date] >= MIN ( Timesheet_NB[Date] )
                && 'Calendar'[Date] <= MAX ( Timesheet_NB[Date] )
        ),
        USERELATIONSHIP ( 'Calendar'[Date], 'Timesheet_NB'[Date] ),
        USERELATIONSHIP ( 'Direct Reports_Last_Active'[Employee_ID], Timesheet_NB[Employee] )
    )
RETURN
    Sum_Expected_Hrs

 

 

Earlier though, I located this very elegant measure which calculates the cumulative total of expected hours (CSum_Expected_hrs_total). This measure works really well, and I understand why, but I haven’t been able to adjust it to pull the regular sum of Expected Hours, as i'm trying to do in the above measure. I include it as it may prove a better approach anyway:

 

CSum_Expected_hrs_total =
VAR CurrentDate =
    MAX ( Calendar[Date] )
VAR HoursPerDay =
    ADDCOLUMNS (
        'Direct Reports_Last_Active',
        "Hrs_day",
            CALCULATE (
                SUMX ( 'Direct Reports_Last_Active', 'Direct Reports_Last_Active'[Hrs_per_day] ),
                USERELATIONSHIP ( 'Direct Reports_Last_Active'[Employee_ID], Timesheet_NB[Employee] )
            )
    )
VAR Result =
    CALCULATE (
        SUMX (
            HoursPerDay,
            VAR CurrentStart = 'Direct Reports_Last_Active'[Start_DateFrame]
            VAR CurrentEnd = 'Direct Reports_Last_Active'[Stop_date]
            VAR DaysGone =
                IF (
                    CurrentDate >= CurrentStart,
                    IF (
                        CurrentDate > CurrentEnd,
                        NETWORKDAYS ( CurrentStart, CurrentEnd, 1 ),
                        NETWORKDAYS ( CurrentStart, CurrentDate, 1 )
                    ),
                    0
                )
            RETURN
                [Hrs_day] * DaysGone
        ),
        USERELATIONSHIP ( 'Direct Reports_Last_Active'[Employee_ID], Timesheet_NB[Employee] )
    )
RETURN
    Result

 

Thank you so much!

Martijn

3 Replies