예제 #1
0
        /// <summary>
        /// Performs roll up of target towards the parent for a set of child sccorecards
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <param name="childTargetIds">Target Id's of scorecards which needs to be rolled up</param>
        /// <returns>Rolled up value towards the parent</returns>
        public decimal?CalculateRollupTarget(RollupInfo rollupInfo, List <int> childTargetIds)
        {
            decimal?rollupValue = null;
            var     targetId    = childTargetIds?.FirstOrDefault();

            if (targetId.HasValue)
            {
                var childTarget        = targetRepository.Get(targetId.Value);
                var childMonthlyTarget = childTarget?.MonthlyTargets?.FirstOrDefault(x => x.Month == rollupInfo.TargetEntryDate.Month);
                if (childMonthlyTarget != null)
                {
                    if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                    {
                        var childDailyTarget = childTarget.IsCascaded ?
                                               childMonthlyTarget.DailyTargets.FirstOrDefault(x => x.Day == rollupInfo.TargetEntryDate.Day)?.RolledUpGoalValue :
                                               childMonthlyTarget.DailyTargets.FirstOrDefault(x => x.Day == rollupInfo.TargetEntryDate.Day)?.MaxGoalValue;
                        if (childDailyTarget != null)
                        {
                            rollupValue = childDailyTarget;
                        }
                    }
                    else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                    {
                        rollupValue = childTarget.IsCascaded ?
                                      childMonthlyTarget.RolledUpGoalValue :
                                      childMonthlyTarget.MaxGoalValue;
                    }
                }
            }
            return(rollupValue);
        }
예제 #2
0
        /// <summary>
        /// Add/update a monthly rollup entry
        /// </summary>
        /// <param name="parentActual">Parent's actual(rolled up value)</param>
        /// <param name="parentMonthlyActualId">Id of the parent actual entry</param>
        /// <param name="rollupInfo">Rollup information</param>
        private void AddOrUpdateMonthlyRollupEntry(decimal?parentActual,
                                                   int?parentMonthlyActualId, RollupInfo rollupInfo)
        {
            ActualItem rollupEntry = new ActualItem();

            rollupEntry.ActualValue = parentActual;
            // Assign target and scorecard id
            rollupEntry.TargetId    = rollupInfo.ParentTargetId.Value;
            rollupEntry.ScorecardId = rollupInfo.ParentScorecardId;

            // Retrieves the monthly goal for the parent
            rollupEntry.GoalValue = goalCalculator.GetMonthlyGoal(
                rollupInfo.ParentTargetId.Value, rollupInfo.ActualEntry.Date.Month);
            rollupEntry.Date = rollupInfo.ActualEntry.Date;

            if (parentMonthlyActualId.HasValue)
            {
                rollupEntry.Id = parentMonthlyActualId.Value;
                actualsModifier.UpdateMonthlyActual(rollupEntry, rollupInfo.GoalTypeId,
                                                    rollupInfo.Username);
            }
            else
            {
                actualsModifier.AddMonthlyActual(rollupEntry, rollupInfo.GoalTypeId,
                                                 rollupInfo.Username);
            }
        }
예제 #3
0
        /// <summary>
        /// Performs roll up of actuals towards the parent for a set of child sccorecards
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <param name="childTargetIds">Target Id's of scorecards which needs to be
        /// rolled up</param>
        /// <returns>Rolled up value towards the parent</returns>
        public decimal?CalculateRollup(RollupInfo rollupInfo, List <int> childTargetIds)
        {
            decimal?rollupValue = null;
            var     targetId    = childTargetIds?.FirstOrDefault();

            // If tracking method is daily
            if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
            {
                var childDailyActual = dailyActualRepository.GetAll().Where(x =>
                                                                            x.TargetId == targetId &&
                                                                            x.Date == rollupInfo.ActualEntry.Date).FirstOrDefault()?.ActualValue;
                if (childDailyActual != null)
                {
                    rollupValue = childDailyActual;
                }
            }

            // If tracking method is monthly
            else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
            {
                var childMonthlyActual = monthlyActualRepository.GetAll().Where(x =>
                                                                                x.TargetId == targetId &&
                                                                                x.Month == rollupInfo.ActualEntry.Date.Month).FirstOrDefault()?.ActualValue;
                if (childMonthlyActual != null)
                {
                    rollupValue = childMonthlyActual;
                }
            }
            return(rollupValue);
        }
예제 #4
0
        /// <summary>
        /// Traverse the hierarchy down, calculates sum of targets and count of children which
        /// can be considered for calculating average
        /// </summary>
        /// <param name="rollupInfo">Rollup info</param>
        /// <param name="parentTargetId">Parent target</param>
        /// <param name="sumOfTargets">Sum of actuals which is needed for calculating average</param>
        /// <param name="childTargetCount">Number of child targets which needs to be
        /// considered while calculating actual</param>
        private void CalculateRollupTargetValueRecursively(RollupInfo rollupInfo, int parentTargetId,
                                                           ref decimal?sumOfTargets, ref int childTargetCount)
        {
            // Retrieve all child targets
            var childTargets = targetRepository.GetAll().Where(x =>
                                                               x.ParentTargetId == parentTargetId &&
                                                               x.IsActive).Select(x =>
                                                                                  new { Id = x.Id, IsCascaded = x.IsCascaded, MonthlyTargets = x.MonthlyTargets }).ToList();

            foreach (var childTarget in childTargets)
            {
                if (!childTarget.IsCascaded)
                {
                    var childMonthlyTarget = childTarget?.MonthlyTargets?.FirstOrDefault(x => x.Month == rollupInfo.TargetEntryDate.Month);
                    if (childMonthlyTarget != null)
                    {
                        if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                        {
                            var childDailyTarget = childMonthlyTarget.DailyTargets.FirstOrDefault(x => x.Day == rollupInfo.TargetEntryDate.Day)?.MaxGoalValue;
                            if (childDailyTarget != null)
                            {
                                ++childTargetCount;
                                if (sumOfTargets == null)
                                {
                                    sumOfTargets = childDailyTarget;
                                }
                                else
                                {
                                    sumOfTargets += childDailyTarget;
                                }
                            }
                        }
                        else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                        {
                            ++childTargetCount;
                            if (sumOfTargets == null)
                            {
                                sumOfTargets = childMonthlyTarget.MaxGoalValue;
                            }
                            else
                            {
                                sumOfTargets += childMonthlyTarget.MaxGoalValue;
                            }
                        }
                    }
                }
            }

            // Traverse down recursively
            foreach (var childTarget in childTargets)
            {
                CalculateRollupTargetValueRecursively(rollupInfo, childTarget.Id, ref sumOfTargets,
                                                      ref childTargetCount);
            }
        }
예제 #5
0
 /// <summary>
 /// Add/update a target rollup
 /// </summary>
 /// <param name="parentActual">Parent's actual(rolled up value)</param>
 /// <param name="parentMonthlyActualId">Id of the parent actual entry</param>
 /// <param name="rollupInfo">Rollup information</param>
 private void AddOrUpdateTargetRollup(RollupInfo rollupInfo, IList <RollupTargetItem> rollupTargets)
 {
     if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
     {
         targetModifier.AddOrUpdateDailyTargets(rollupInfo.ParentTargetId.Value, rollupTargets, rollupInfo.Username);
     }
     else
     {
         targetModifier.AddOrUpdateMonthlyTargets(rollupInfo.ParentTargetId.Value, rollupTargets, rollupInfo.Username);
     }
 }
예제 #6
0
        /// <summary>
        /// Calculates the roll up value based on the rollup method set
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <returns>Calculated rollup value</returns>
        private decimal?CalculateRollupTargetValue(RollupInfo rollupInfo)
        {
            decimal?rolledupValue = null;
            // Retrieve all child targets
            var childTargetIds = targetRepository.GetAll().Where(x =>
                                                                 x.ParentTargetId == rollupInfo.ParentTargetId &&
                                                                 x.IsActive).Select(y => y.Id).ToList();

            switch (rollupInfo.RollupMethodId)
            {
            // "Sum of Children"
            case Constants.RollupMethodSumOfChildren:
            {
                IRollupStrategy sumOfChildrenRollup = CreateSumOfChildrenRollupStrategy();
                rolledupValue = sumOfChildrenRollup.CalculateRollupTarget(rollupInfo,
                                                                          childTargetIds);
                break;
            }

            // "Average of Children"
            case Constants.RollupMethodAverageOfChildren:
            {
                IRollupStrategy avgOfChildrentRollup =
                    CreateAverageOfChildrenRollupStrategy();
                rolledupValue = avgOfChildrentRollup.CalculateRollupTarget(rollupInfo,
                                                                           childTargetIds);
                break;
            }

            // "Same as Child"
            case Constants.RollupMethodSameAsChild:
            {
                IRollupStrategy sameAsChildRollup = CreateSameAsChildRollupStrategy();
                rolledupValue = sameAsChildRollup.CalculateRollupTarget(rollupInfo,
                                                                        childTargetIds);
                break;
            }
            }

            // Round the rolled up value to two decimal places
            if (rolledupValue.HasValue)
            {
                var rollupValue = decimal.Round(rolledupValue.Value, 2, MidpointRounding.AwayFromZero);
                if (rollupInfo.DataTypeId == Constants.DataTypeWholeNumber)
                {
                    rollupValue = decimal.Round(rolledupValue.Value, 0, MidpointRounding.AwayFromZero);
                }

                return(rollupValue);
            }

            return(rolledupValue);
        }
예제 #7
0
        /// <summary>
        /// Rollup an actual entry recursively
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        private void RollupRecursively(RollupInfo rollupInfo)
        {
            while (rollupInfo.ParentTargetId != null)
            {
                decimal?rolledupValue       = CalculateRollupValue(rollupInfo);
                var     currentRollupTarget = targetRepository.Get(rollupInfo.ParentTargetId.Value);

                // If parent actuals are calculated, just roll them up
                int?parentDailyActualId   = null;
                int?parentMonthlyActualId = null;

                // Depending upon the tracking method, retrieve the actual entries
                // of the parent for which we need to roll up
                if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                {
                    parentDailyActualId = dailyActualRepository.GetAll().Where(x =>
                                                                               x.TargetId == rollupInfo.ParentTargetId &&
                                                                               x.Date == rollupInfo.ActualEntry.Date).Select
                                              (x => new { Id = x.Id }).FirstOrDefault()?.Id;

                    AddOrUpdateDailyRollupEntry(rolledupValue, parentDailyActualId,
                                                rollupInfo);
                }
                else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                {
                    parentMonthlyActualId = monthlyActualRepository.GetAll().Where(x =>
                                                                                   x.TargetId == rollupInfo.ParentTargetId &&
                                                                                   x.Month == rollupInfo.ActualEntry.Date.Month).Select
                                                (x => new { Id = x.Id }).FirstOrDefault()?.Id;

                    AddOrUpdateMonthlyRollupEntry(rolledupValue, parentMonthlyActualId,
                                                  rollupInfo);
                }

                if (rollupInfo.UpdateRecordable)
                {
                    recordablesCalculator.TrackRecordables(rollupInfo.ParentTargetId.Value, rollupInfo.ActualEntry, rollupInfo.Username);
                }

                // Change the parent target and scorecard id's to the next parent
                // and call recursively
                rollupInfo.ParentTargetId    = currentRollupTarget.ParentTarget?.Id;
                rollupInfo.ParentScorecardId = currentRollupTarget.ParentTarget?.ScorecardId;
                rollupInfo.RollupMethodId    = currentRollupTarget.ParentTarget?.RollUpMethodId;
                RollupRecursively(rollupInfo);
            }
        }
예제 #8
0
 /// <summary>
 /// Performs roll up for targets for a specific Month
 /// </summary>
 /// <param name="target">The target.</param>
 /// <param name="selectedDate">The selected date.</param>
 /// <param name="username">Logged in user name</param>
 /// <param name="updateStatus">if set to <c>true</c> [update status].</param>
 public virtual void PerformTargetRollup(Target target, DateTime selectedDate, string username, bool updateStatus)
 {
     if (target.ParentTargetId != null)
     {
         // Fill the parameters needed for rollup operation
         RollupInfo rollupInfo = new RollupInfo();
         rollupInfo.Username          = username;
         rollupInfo.ParentTargetId    = target.ParentTargetId;
         rollupInfo.ParentScorecardId = target.ParentTarget.ScorecardId;
         rollupInfo.RollupMethodId    = target.ParentTarget.RollUpMethodId;
         rollupInfo.DataTypeId        = target.Metric.DataTypeId;
         rollupInfo.GoalTypeId        = target.Metric.GoalTypeId;
         rollupInfo.TrackingMethodId  = target.TrackingMethodId;
         // Invoke the recursive rollup operation
         RollupTargetRecursively(rollupInfo, selectedDate, updateStatus);
     }
 }
예제 #9
0
        /// <summary>
        /// Performs roll up of actuals towards the parent for a set of child sccorecards
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <param name="childTargetIds">Target Id's of scorecards which needs to be rolled up</param>
        /// <returns>Rolled up value towards the parent</returns>
        public decimal?CalculateRollup(RollupInfo rollupInfo, List <int> childTargetIds)
        {
            decimal?sumOfChilds = null;

            foreach (var targetId in childTargetIds)
            {
                if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                {
                    var childDailyActual = dailyActualRepository.GetAll().Where(x =>
                                                                                x.TargetId == targetId &&
                                                                                x.Date == rollupInfo.ActualEntry.Date).FirstOrDefault()?.ActualValue;
                    if (childDailyActual != null)
                    {
                        if (sumOfChilds == null)
                        {
                            sumOfChilds = childDailyActual;
                        }
                        else
                        {
                            sumOfChilds += childDailyActual;
                        }
                    }
                }
                else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                {
                    var childMonthlyActual = monthlyActualRepository.GetAll().Where(x =>
                                                                                    x.TargetId == targetId &&
                                                                                    x.Month == rollupInfo.ActualEntry.Date.Month).
                                             FirstOrDefault()?.ActualValue;
                    if (childMonthlyActual != null)
                    {
                        if (sumOfChilds == null)
                        {
                            sumOfChilds = childMonthlyActual;
                        }
                        else
                        {
                            sumOfChilds += childMonthlyActual;
                        }
                    }
                }
            }
            return(sumOfChilds);
        }
예제 #10
0
        /// <summary>
        /// Performs the rollup on succeeding days on previous day update.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="actualEntryStartDate">The actual entry start date.</param>
        /// <param name="actualEntryEndDate">The actual entry end date.</param>
        /// <param name="username">The username.</param>
        public virtual void PerformRollupOnSucceedingDays(Target target, DateTime actualEntryStartDate, DateTime actualEntryEndDate, string username)
        {
            if (target.ParentTargetId != null)
            {
                // Fill the parameters needed for rollup operation
                RollupInfo rollupInfo = new RollupInfo();
                rollupInfo.ActualEntry       = new ActualItem();
                rollupInfo.Username          = username;
                rollupInfo.ParentTargetId    = target.ParentTargetId;
                rollupInfo.ParentScorecardId = target.ParentTarget.ScorecardId;
                rollupInfo.RollupMethodId    = target.ParentTarget.RollUpMethodId;
                rollupInfo.DataTypeId        = target.Metric.DataTypeId;
                rollupInfo.GoalTypeId        = target.Metric.GoalTypeId;
                rollupInfo.TrackingMethodId  = target.TrackingMethodId;

                // Invoke the recursive rollup operation
                RollupRecursivelyForSucceedingDays(rollupInfo, actualEntryStartDate, actualEntryEndDate);
            }
        }
예제 #11
0
        /// <summary>
        /// Updates the daily actual status.
        /// </summary>
        /// <param name="rollupInfo">The rollup information.</param>
        /// <param name="rollupTargets">The rollup targets.</param>
        private void UpdateActualStatus(RollupInfo rollupInfo, DateTime selectedDate, IList <RollupTargetItem> rollupTargets, ref bool updateStatus)
        {
            if (!updateStatus)
            {
                // if rollup targets and actual entry for the given child is missing, check whether roll-up actual from other children exists for the parent target
                updateStatus = (dailyActualRepository.GetAll().Where(x => x.TargetId == rollupInfo.ParentTargetId && x.Date.Month == selectedDate.Month)?.Count() ?? 0) > 0;
            }

            if (rollupTargets.Any(x => x.TargetEntryDate.Month == selectedDate.Month) && updateStatus)
            {
                if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                {
                    actualsModifier.UpdateDailyActualStatusAndGoalForMonth(rollupInfo.ParentTargetId.Value, selectedDate, rollupInfo.Username);
                }
                else
                {
                    actualsModifier.UpdateMonthlyActualStatusAndGoalForMonth(rollupInfo.ParentTargetId.Value, selectedDate, rollupInfo.Username);
                }
            }
        }
예제 #12
0
        /// <summary>
        /// Performs roll up of targets towards the parent for a set of child scorecards
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <param name="childTargetIds">Target Id's of scorecards which needs to be
        /// rolled up</param>
        /// <returns>Rolled up value towards the parent</returns>
        public decimal?CalculateRollupTarget(RollupInfo rollupInfo, List <int> childTargetIds)
        {
            decimal?sumOfTargets     = null;
            int     childTargetCount = 0;

            if (rollupInfo.ParentTargetId != null)
            {
                // Calculate the roll up value recursively for the parent by traversing down
                CalculateRollupTargetValueRecursively(rollupInfo, rollupInfo.ParentTargetId.Value,
                                                      ref sumOfTargets, ref childTargetCount);

                // Find the average of children
                if (sumOfTargets != null && childTargetCount > 0)
                {
                    // Add to the cumulative figure
                    return(sumOfTargets / childTargetCount);
                }
            }

            return(null);
        }
예제 #13
0
        /// <summary>
        /// Performs roll up for an actual entry
        /// </summary>
        /// <param name="actualEntry">Actual entry to rollup</param>
        /// <param name="username">Logged in user name</param>
        public virtual void PerformRollup(ActualItem actualEntry, bool updateRecordable, string username)
        {
            // Find target with the given id
            var target = targetRepository.Get(actualEntry.TargetId);

            if (target.ParentTargetId != null)
            {
                // Fill the parameters needed for rollup operation
                RollupInfo rollupInfo = new RollupInfo();
                rollupInfo.ActualEntry       = actualEntry;
                rollupInfo.Username          = username;
                rollupInfo.ParentTargetId    = target.ParentTargetId;
                rollupInfo.ParentScorecardId = target.ParentTarget.ScorecardId;
                rollupInfo.RollupMethodId    = target.ParentTarget.RollUpMethodId;
                rollupInfo.DataTypeId        = target.Metric.DataTypeId;
                rollupInfo.GoalTypeId        = target.Metric.GoalTypeId;
                rollupInfo.TrackingMethodId  = target.TrackingMethodId;
                rollupInfo.UpdateRecordable  = updateRecordable;

                // Invoke the recursive rollup operation
                RollupRecursively(rollupInfo);
            }
        }
예제 #14
0
        /// <summary>
        /// Rollup target recursively
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        private void RollupTargetRecursively(RollupInfo rollupInfo, DateTime selectedDate, bool updateStatus)
        {
            while (rollupInfo.ParentTargetId != null)
            {
                // If parent targets are calculated, just roll them up
                int?parentDailyTargetId   = null;
                int?parentMonthlyTargetId = null;

                DateTime rollupStartDate = new DateTime(selectedDate.Year, selectedDate.Month, 1);
                DateTime rollupEndDate   = new DateTime(selectedDate.Year, selectedDate.Month, DateTime.DaysInMonth(selectedDate.Year, selectedDate.Month));

                decimal?rolledupValue;

                var rollupTargets = new List <RollupTargetItem>();

                var currentRollupTarget = targetRepository.Get(rollupInfo.ParentTargetId.Value);

                if (currentRollupTarget.EffectiveStartDate > rollupStartDate)
                {
                    rollupStartDate = currentRollupTarget.EffectiveStartDate;
                }

                if (currentRollupTarget.EffectiveEndDate < rollupEndDate)
                {
                    rollupEndDate = currentRollupTarget.EffectiveEndDate;
                }

                var parentMonthlyTarget = currentRollupTarget?.MonthlyTargets.FirstOrDefault(x => x.Month == selectedDate.Month);

                // Depending upon the tracking method, retrieve the targets
                // of the parent for which we need to roll up
                if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                {
                    IList <DailyTargetItem> dailyTargets = new List <DailyTargetItem>();
                    if (parentMonthlyTarget != null)
                    {
                        dailyTargets = DistributeDailyTarget(currentRollupTarget, parentMonthlyTarget, selectedDate.Year);
                    }

                    while (rollupStartDate <= rollupEndDate)
                    {
                        rollupInfo.TargetEntryDate = rollupStartDate;
                        rolledupValue = CalculateRollupTargetValue(rollupInfo);

                        parentDailyTargetId = parentMonthlyTarget?.DailyTargets.FirstOrDefault(x => x.Day == rollupStartDate.Day)?.Id;
                        var dailyTarget      = dailyTargets?.FirstOrDefault(x => x.Day == rollupStartDate.Day && !x.IsOutofRange);
                        var rollupTargetItem = new RollupTargetItem
                        {
                            TargetId        = parentDailyTargetId,
                            TargetEntryDate = rollupStartDate,
                            RollUpValue     = rolledupValue,
                            GoalValue       = dailyTarget?.GoalValue,
                            IsHoliday       = dailyTarget?.IsHoliday ?? false
                        };
                        rollupTargets.Add(rollupTargetItem);
                        rollupStartDate = rollupStartDate.AddDays(1);
                    }
                }
                else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                {
                    rollupInfo.TargetEntryDate = rollupStartDate;
                    rolledupValue         = CalculateRollupTargetValue(rollupInfo);
                    parentMonthlyTargetId = parentMonthlyTarget?.Id;

                    var rollupTargetItem = new RollupTargetItem
                    {
                        TargetId        = parentMonthlyTargetId,
                        TargetEntryDate = rollupStartDate,
                        RollUpValue     = rolledupValue
                    };
                    rollupTargets.Add(rollupTargetItem);
                }

                AddOrUpdateTargetRollup(rollupInfo, rollupTargets);

                if (currentRollupTarget.CascadedMetricsTrackingMethodId == (int)CascadedMetricsTrackingMethod.RolledUpTargets || updateStatus)
                {
                    UpdateActualStatus(rollupInfo, rollupStartDate, rollupTargets, ref updateStatus);
                }

                rollupInfo.ParentTargetId    = currentRollupTarget.ParentTarget?.Id;
                rollupInfo.ParentScorecardId = currentRollupTarget.ParentTarget?.ScorecardId;
                rollupInfo.RollupMethodId    = currentRollupTarget.ParentTarget?.RollUpMethodId;
                RollupTargetRecursively(rollupInfo, selectedDate, updateStatus);
            }
        }
예제 #15
0
        /// <summary>
        /// Rollup recursively for succeeding days on previous day update.
        /// </summary>
        /// <param name="rollupInfo">The rollup information.</param>
        /// <param name="actualEntryStartDate">The actual entry start date.</param>
        /// <param name="actualEntryEndDate">The actual entry end date.</param>
        private void RollupRecursivelyForSucceedingDays(RollupInfo rollupInfo, DateTime actualEntryStartDate, DateTime actualEntryEndDate)
        {
            while (rollupInfo.ParentTargetId != null)
            {
                decimal? rolledupValue;
                DateTime startDate = actualEntryStartDate;
                // If parent actuals are calculated, just roll them up
                int?parentDailyActualId   = null;
                int?parentMonthlyActualId = null;
                var currentRollupTarget   = targetRepository.Get(rollupInfo.ParentTargetId.Value);

                // Depending upon the tracking method, retrieve the actual entries
                // of the parent for which we need to roll up
                if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                {
                    while (startDate <= actualEntryEndDate)
                    {
                        rollupInfo.ActualEntry.Date = startDate;
                        rolledupValue = CalculateRollupValue(rollupInfo);

                        if (rolledupValue.HasValue)
                        {
                            parentDailyActualId = dailyActualRepository.GetAll().Where(x =>
                                                                                       x.TargetId == rollupInfo.ParentTargetId &&
                                                                                       x.Date == startDate).Select
                                                      (x => new { Id = x.Id }).FirstOrDefault()?.Id;

                            if (parentDailyActualId.HasValue)
                            {
                                AddOrUpdateDailyRollupEntry(rolledupValue, parentDailyActualId,
                                                            rollupInfo);
                            }
                        }
                        startDate = startDate.AddDays(1);
                    }
                }
                else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                {
                    while (startDate.Month <= actualEntryEndDate.Month)
                    {
                        rollupInfo.ActualEntry.Date = startDate;
                        rolledupValue = CalculateRollupValue(rollupInfo);

                        parentMonthlyActualId = monthlyActualRepository.GetAll().Where(x =>
                                                                                       x.TargetId == rollupInfo.ParentTargetId &&
                                                                                       x.Month == startDate.Month).Select
                                                    (x => new { Id = x.Id }).FirstOrDefault()?.Id;

                        if (parentMonthlyActualId.HasValue)
                        {
                            AddOrUpdateMonthlyRollupEntry(rolledupValue, parentMonthlyActualId,
                                                          rollupInfo);
                            startDate = startDate.AddMonths(1);
                        }
                    }
                }

                // Change the parent target and scorecard id's to the next parent
                // and call recursively
                rollupInfo.ParentTargetId    = currentRollupTarget.ParentTarget?.Id;
                rollupInfo.ParentScorecardId = currentRollupTarget.ParentTarget?.ScorecardId;
                rollupInfo.RollupMethodId    = currentRollupTarget.ParentTarget?.RollUpMethodId;
                RollupRecursivelyForSucceedingDays(rollupInfo, actualEntryStartDate, actualEntryEndDate);
            }
        }
예제 #16
0
        /// <summary>
        /// Rollup target recursively
        /// </summary>
        /// <param name="rollupInfo">Rollup information</param>
        /// <param name="updateStatus">if set to <c>true</c> [update status].</param>
        private void RollupTargetRecursively(RollupInfo rollupInfo, bool updateStatus)
        {
            while (rollupInfo.ParentTargetId != null)
            {
                // If parent targets are calculated, just roll them up
                int?parentDailyTargetId   = null;
                int?parentMonthlyTargetId = null;
                int startMonth;

                decimal?rolledupValue;
                var     rollupTargets = new List <RollupTargetItem>();

                var currentRollupTarget = targetRepository.Get(rollupInfo.ParentTargetId.Value);

                DateTime currentDate       = TimeZoneUtility.GetCurrentTimestamp().Date;
                DateTime previousMonthDate = currentDate.AddMonths(-1);
                DateTime targetStartDate   = currentRollupTarget.EffectiveStartDate;
                DateTime targetEndDate     = currentRollupTarget.EffectiveEndDate;
                startMonth = previousMonthDate.Month;
                if (previousMonthDate < targetStartDate)
                {
                    startMonth = targetStartDate.Month;
                }

                int endMonth   = currentRollupTarget.EffectiveEndDate.Month;
                int targetYear = targetStartDate.Year;

                while (startMonth <= endMonth)
                {
                    var      parentMonthlyTarget = currentRollupTarget?.MonthlyTargets.FirstOrDefault(x => x.Month == startMonth);
                    DateTime monthStartDate      = new DateTime(targetYear, startMonth, 1);
                    if (monthStartDate < targetStartDate)
                    {
                        monthStartDate = targetStartDate;
                    }

                    // Depending upon the tracking method, retrieve the targets
                    // of the parent for which we need to roll up
                    if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                    {
                        DateTime monthEndDate = new DateTime(targetYear, startMonth, DateTime.DaysInMonth(targetYear, startMonth));
                        IList <DailyTargetItem> dailyTargets = new List <DailyTargetItem>();

                        if (monthEndDate > targetEndDate)
                        {
                            monthEndDate = targetEndDate;
                        }

                        if (parentMonthlyTarget != null)
                        {
                            dailyTargets = DistributeDailyTarget(currentRollupTarget, parentMonthlyTarget, targetYear);
                        }

                        while (monthStartDate <= monthEndDate)
                        {
                            rollupInfo.TargetEntryDate = monthStartDate;
                            rolledupValue       = CalculateRollupTargetValue(rollupInfo);
                            parentDailyTargetId = parentMonthlyTarget?.DailyTargets.FirstOrDefault(x => x.Day == monthStartDate.Day)?.Id;

                            var dailyTarget = dailyTargets?.FirstOrDefault(x => x.Day == monthStartDate.Day && !x.IsOutofRange);

                            var rollupTargetItem = new RollupTargetItem
                            {
                                TargetId        = parentDailyTargetId,
                                TargetEntryDate = monthStartDate,
                                RollUpValue     = rolledupValue,
                                GoalValue       = dailyTarget?.GoalValue,
                                IsHoliday       = dailyTarget?.IsHoliday ?? false
                            };
                            rollupTargets.Add(rollupTargetItem);
                            monthStartDate = monthStartDate.AddDays(1);
                        }
                    }
                    else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                    {
                        rollupInfo.TargetEntryDate = monthStartDate;
                        rolledupValue         = CalculateRollupTargetValue(rollupInfo);
                        parentMonthlyTargetId = parentMonthlyTarget?.Id;

                        var rollupTargetItem = new RollupTargetItem
                        {
                            TargetId        = parentMonthlyTargetId,
                            TargetEntryDate = monthStartDate,
                            RollUpValue     = rolledupValue
                        };
                        rollupTargets.Add(rollupTargetItem);
                    }
                    startMonth++;
                }

                AddOrUpdateTargetRollup(rollupInfo, rollupTargets);

                if (currentRollupTarget.CascadedMetricsTrackingMethodId == (int)CascadedMetricsTrackingMethod.RolledUpTargets || updateStatus)
                {
                    // update previous month status
                    UpdateActualStatus(rollupInfo, previousMonthDate, rollupTargets, ref updateStatus);
                    // update current month status
                    UpdateActualStatus(rollupInfo, currentDate, rollupTargets, ref updateStatus);
                }

                rollupInfo.ParentTargetId    = currentRollupTarget.ParentTarget?.Id;
                rollupInfo.ParentScorecardId = currentRollupTarget.ParentTarget?.ScorecardId;
                rollupInfo.RollupMethodId    = currentRollupTarget.ParentTarget?.RollUpMethodId;
                RollupTargetRecursively(rollupInfo, updateStatus);
            }
        }
예제 #17
0
        /// <summary>
        /// Traverse the hierarchy down, calculates sum of actuals and count of children which
        /// can be considered for calculating average
        /// </summary>
        /// <param name="rollupInfo">Rollup info</param>
        /// <param name="parentTargetId">Parent target</param>
        /// <param name="sumOfActuals">Sum of actuals which is needed for calculating average</param>
        /// <param name="childTargetCount">Number of child targets which needs to be
        /// considered while calculating actual</param>
        private void CalculateRollupValueRecursively(RollupInfo rollupInfo, int parentTargetId,
                                                     ref decimal?sumOfActuals, ref int childTargetCount)
        {
            // Retrieve all child targets
            var childTargets = targetRepository.GetAll().Where(x =>
                                                               x.ParentTargetId == parentTargetId &&
                                                               x.IsActive).Select(x =>
                                                                                  new { Id = x.Id, IsCascaded = x.IsCascaded }).ToList();

            // Iterate all child targets and sum up the actual values and count
            foreach (var target in childTargets)
            {
                // While calculating average in a level, we should avoid
                // scorecards(basically targets) which are cascaded further
                // down(Or consider only scorecards where actuals can be entered directly)
                if (target.IsCascaded == false)
                {
                    if (rollupInfo.TrackingMethodId == Constants.TrackingMethodDaily)
                    {
                        var childDailyActual = dailyActualRepository.GetAll().Where(x =>
                                                                                    x.TargetId == target.Id &&
                                                                                    x.Date == rollupInfo.ActualEntry.Date).FirstOrDefault()?.ActualValue;
                        if (childDailyActual != null)
                        {
                            ++childTargetCount;
                            if (sumOfActuals == null)
                            {
                                sumOfActuals = childDailyActual;
                            }
                            else
                            {
                                sumOfActuals += childDailyActual;
                            }
                        }
                    }
                    else if (rollupInfo.TrackingMethodId == Constants.TrackingMethodMonthly)
                    {
                        var childMonthlyActual = monthlyActualRepository.GetAll().Where(x =>
                                                                                        x.TargetId == target.Id &&
                                                                                        x.Month == rollupInfo.ActualEntry.Date.Month).
                                                 FirstOrDefault()?.ActualValue;
                        if (childMonthlyActual != null)
                        {
                            ++childTargetCount;
                            if (sumOfActuals == null)
                            {
                                sumOfActuals = childMonthlyActual;
                            }
                            else
                            {
                                sumOfActuals += childMonthlyActual;
                            }
                        }
                    }
                }
            }

            // Traverse down recursively
            foreach (var childTarget in childTargets)
            {
                CalculateRollupValueRecursively(rollupInfo, childTarget.Id, ref sumOfActuals,
                                                ref childTargetCount);
            }
        }