From 8aa92097f35eb7589def9adfcf9fd3de67b1f3ef Mon Sep 17 00:00:00 2001 From: Jamie Carter <9541902+jamiecarter7@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:04:55 +0100 Subject: [PATCH] Goal lines refactoring (#5258) **Story card:** None - bug fix ## Because Needed to refactor monthIndexFromDateKey() function. This will be needed in a follow up PR that fixes a bug on the dashed lines of the overdue chart ## This addresses Refactor complete plus some additional work to simplify the goal lines functionality and make it easier to follow Changes: - goalPeriodValue() renamed to getThreeMonthAverageAndImprovementRatio() - improvement ratio is calculated inside the getThreeMonthAverageAndImprovementRatio() rather than passing data around - simplified check for isEndMonthOfYear() (previously named isLastDateKeysArrayMonthDec) - improved variable naming - monthIndexFromDateKey() uses built in javascript function - calculateGoalUpwards() and calculateGoalDownwards() have parameter names that match the data being passed (monthValue -> threeMonthAverage) - correction to how the remaining months in the year is calculated: ``` const monthsRemainingForYear = monthThreeIndex === 11 ? 12 : 11 - monthThreeIndex; ``` ## Test instructions Switch between this branch and the current master branch to check that the figures are the same. Note: there was a previous miscalculation on the goal lines. When checking the figures are the same there might be a small chance 'this branch/PR' shows a figure that is 1% less than that shows on the current master. This is correct - the master was +0.0083 higher than it should have been after running the calculations. Figures are rounded so there should be no change unless it crosses to the next integer. To view the goal lines add the commented line to your reports.js file ``` const enabledRegions = { IN: ["state"], // add this line <- BD: ["organization", "state", "district"], ET: ["organization", "state"], LK: ["organization"], }; ``` the line for copying ``` IN: ["state"], ``` --------- Co-authored-by: Priyanga P Kini --- app/assets/javascripts/common/reports.js | 86 ++++++++++-------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/app/assets/javascripts/common/reports.js b/app/assets/javascripts/common/reports.js index 1a67bb119b..fbeaa8d359 100644 --- a/app/assets/javascripts/common/reports.js +++ b/app/assets/javascripts/common/reports.js @@ -662,8 +662,7 @@ Reports = function ({ } function calculateGoal(periodValues, goalDownwards) { - const { threeMonthAverage, monthThreeIndexOfYear } = goalPeriodValue(periodValues); - const improvementRatio = relativeImprovementRatio(monthThreeIndexOfYear); + const { threeMonthAverage, improvementRatio } = getThreeMonthAverageAndImprovementRatio(periodValues); if (goalDownwards) { return calculateGoalDownwards(threeMonthAverage, improvementRatio); @@ -671,74 +670,62 @@ Reports = function ({ return calculateGoalUpwards(threeMonthAverage, improvementRatio); } - function goalPeriodValue(periodValues) { - const dateKeysArray = Object.keys(periodValues); + function getThreeMonthAverageAndImprovementRatio(periodValues) { + const evaluationMonth = "Dec" + const dateKeys = Object.keys(periodValues); + const evaluationMonthKeys = dateKeys.filter((item) => item.includes(evaluationMonth)); - const decemberKeys = dateKeysArray.filter((item) => item.includes("Dec")); - const isLastDateKeysArrayMonthDec = - monthIndexFromDateString(dateKeysArray[dateKeysArray.length - 1]) === 11; - if (isLastDateKeysArrayMonthDec) { - decemberKeys.splice(-1); + const [lastMonthKey] = dateKeys.slice(-1); + const isEndMonthOfYear = lastMonthKey.includes(evaluationMonth); + if (isEndMonthOfYear) { + evaluationMonthKeys.splice(-1); } - const mostRecentDecemberKey = decemberKeys[decemberKeys.length - 1]; - const indexOfLatestDecember = dateKeysArray.indexOf(mostRecentDecemberKey); + + const mostEvaluationMonthKey = evaluationMonthKeys[evaluationMonthKeys.length - 1]; + const mostEvaluationMonthKeyIndex = dateKeys.indexOf(mostEvaluationMonthKey); const monthThreeDateKey = - indexOfLatestDecember < defaultMonthsRequired - 1 - ? dateKeysArray[defaultMonthsRequired - 1] // month 6 - : mostRecentDecemberKey; // december + mostEvaluationMonthKeyIndex < defaultMonthsRequired - 1 + ? dateKeys[defaultMonthsRequired - 1] // month 6 + : mostEvaluationMonthKey; // eveluation month + + const monthThreeIndex = dateKeys.indexOf(monthThreeDateKey); const monthThreeValue = periodValues[monthThreeDateKey]; - const indexOfMonthThreeInDateKeys = dateKeysArray.indexOf(monthThreeDateKey); - const monthTwoValue = periodValues[dateKeysArray[indexOfMonthThreeInDateKeys - 1]]; - const monthOneValue = periodValues[dateKeysArray[indexOfMonthThreeInDateKeys - 2]]; + const monthTwoValue = periodValues[dateKeys[monthThreeIndex - 1]]; + const monthOneValue = periodValues[dateKeys[monthThreeIndex - 2]]; const sumValues = monthOneValue + monthTwoValue + monthThreeValue; const threeMonthAverage = sumValues === 0 ? 0 : sumValues / 3; + + const monthThreeIndexOfYear = monthIndexFromDateKey(monthThreeDateKey); + const improvementRatio = relativeImprovementRatio(monthThreeIndexOfYear); - const monthThreeIndexOfYear = monthIndexFromDateString(monthThreeDateKey); return { threeMonthAverage, - monthThreeIndexOfYear, + improvementRatio, }; } - function monthIndexFromDateString(dateString) { - const [month, year] = dateString.split("-"); - const months = [ - "jan", - "feb", - "mar", - "apr", - "may", - "jun", - "jul", - "aug", - "sep", - "oct", - "nov", - "dec", - ]; - - return months.indexOf(month.toLowerCase()); + function monthIndexFromDateKey(dateString) { + return new Date(dateString).getMonth(); } - function calculateGoalUpwards(monthValue, improvementRatio) { - const goal = monthValue + (100 - monthValue) * improvementRatio; - return Math.ceil(goal); + function relativeImprovementRatio(monthThreeIndex) { + const annualRelativeImprovement = 0.1; // 10% + const monthlyRelativeImprovement = annualRelativeImprovement / 12; + const monthsRemainingForYear = monthThreeIndex === 11 ? 12 : 11 - monthThreeIndex; // dec = 12, jan = 11... nov = 1 + return monthlyRelativeImprovement * monthsRemainingForYear; } - function calculateGoalDownwards(monthValue, improvementRatio) { - const goal = monthValue - monthValue * improvementRatio; - return Math.floor(goal); + function calculateGoalUpwards(threeMonthAverage, improvementRatio) { + const goal = threeMonthAverage + ((100 - threeMonthAverage) * improvementRatio); + return Math.ceil(goal); } - function relativeImprovementRatio(goalMonthIndex) { - const defaultRelativeImprovementPercentage = 10; - const improvementPercentagePerMonth = - defaultRelativeImprovementPercentage / 100 / 12; - const monthsRemainingInYear = 12 - (goalMonthIndex % 11); // dec is full year (0 index) - return improvementPercentagePerMonth * monthsRemainingInYear; + function calculateGoalDownwards(threeMonthAverage, improvementRatio) { + const goal = threeMonthAverage - (threeMonthAverage * improvementRatio); + return Math.floor(goal); } // - canvas drawing @@ -1693,7 +1680,6 @@ function baseBarChartConfig() { }; } - // [Segment] Functions // /**