From 0ae08e85b9b4ecea23edd010f2b75cbf25ab3ed7 Mon Sep 17 00:00:00 2001 From: Danielle Mayabb Date: Tue, 30 May 2023 11:43:24 -0700 Subject: [PATCH 1/2] Account for user journey when calculating days in summary --- config/config.php | 6 +++++ config/config.template | 7 ++++++ config/config.test.php | 7 ++++++ .../action/GetHolidaySummaryReportAction.php | 2 +- web/js/holidayManagement.js | 25 +++++++++++++++++++ web/services/HolidayService.php | 21 +++++++++++++--- 6 files changed, 63 insertions(+), 5 deletions(-) diff --git a/config/config.php b/config/config.php index c220f9704..9a2a21534 100644 --- a/config/config.php +++ b/config/config.php @@ -160,6 +160,12 @@ functionality to PhpReport */ define ('YEARLY_HOLIDAY_HOURS', 184); +/** + * @name STANDARD_WORKING_DAY + * @global int standard working day length (i.e., journey) + */ +define ('STANDARD_WORKING_DAY', 8); + /** * @name ALL_USERS_GROUP * @global string users group used for retrieving all users diff --git a/config/config.template b/config/config.template index 6aa9f7612..3d3840a37 100644 --- a/config/config.template +++ b/config/config.template @@ -160,6 +160,13 @@ define('DAO_BACKEND', 'PostgreSQL'); */ define ('YEARLY_HOLIDAY_HOURS', 184); +/** + * @name STANDARD_WORKING_DAY + * @global int standard working day length (i.e., journey) + */ +define ('STANDARD_WORKING_DAY', 8); + + /** * @name ALL_USERS_GROUP * @global string users group used for retrieving all users diff --git a/config/config.test.php b/config/config.test.php index 66f63dc86..aea97ee38 100644 --- a/config/config.test.php +++ b/config/config.test.php @@ -160,6 +160,13 @@ functionality to PhpReport */ define ('YEARLY_HOLIDAY_HOURS', 184); +/** + * @name STANDARD_WORKING_DAY + * @global int standard working day length (i.e., journey) + */ +define ('STANDARD_WORKING_DAY', 8); + + /** * @name ALL_USERS_GROUP * @global string users group used for retrieving all users diff --git a/model/facade/action/GetHolidaySummaryReportAction.php b/model/facade/action/GetHolidaySummaryReportAction.php index 7549dde5d..fababd03e 100644 --- a/model/facade/action/GetHolidaySummaryReportAction.php +++ b/model/facade/action/GetHolidaySummaryReportAction.php @@ -72,7 +72,7 @@ protected function doExecute() ); $validJourney = array_pop($validJourney); $validJourney = $validJourney ? $validJourney->getJourney() : 0; - $leaves = HolidayService::groupByWeeks($leaves, $this->weeks); + $leaves = HolidayService::groupByWeeks($leaves, $this->weeks, $journeyHistories); if (count($leaves) == 0) { $leaves = $this->weeks; } diff --git a/web/js/holidayManagement.js b/web/js/holidayManagement.js index 8e21733ca..5f8d11712 100644 --- a/web/js/holidayManagement.js +++ b/web/js/holidayManagement.js @@ -57,6 +57,11 @@ function formatMinutesToHours(minutes) { return minutesLeft > 0 ? hours + minutesLeft + "m" : hours; } +function formatMinutesToDecimal(minutes){ + let hours = (minutes / 60).toFixed(1); + return hours; +} + function addDays(date, days) { var result = new Date(date); result.setDate(result.getDate() + days); @@ -259,6 +264,26 @@ var app = new Vue({ coveredDates: [d], }) } + else { + const durationInDecimal = formatMinutesToDecimal(datesAndRanges.dates[d].end - datesAndRanges.dates[d].init); + const duration = formatMinutesToHours(datesAndRanges.dates[d].end - datesAndRanges.dates[d].init); + const journeyDuration = formatMinutesToHours(datesAndRanges.journey * 60); + if (durationInDecimal > datesAndRanges.journey) + { + datesAndRanges.dates[d].hoursOver = (durationInDecimal - datesAndRanges.journey).toFixed(1); + attributes.push({ + highlight: { + color: 'red', + fillMode: 'light', + }, + dates: new Date(d + 'T00:00:00'), + popover: { + label: `Vacation hours (${duration}) longer than workday hours (${journeyDuration})` + }, + coveredDates: [d], + }) + } + } }); return { ranges: attributes, diff --git a/web/services/HolidayService.php b/web/services/HolidayService.php index 6f3dcff23..5c9961f29 100644 --- a/web/services/HolidayService.php +++ b/web/services/HolidayService.php @@ -30,6 +30,7 @@ include_once(PHPREPORT_ROOT . '/model/facade/UsersFacade.php'); include_once(PHPREPORT_ROOT . '/model/vo/UserVO.php'); require_once(PHPREPORT_ROOT . '/util/LoginManager.php'); +include_once(PHPREPORT_ROOT . '/util/ConfigurationParametersManager.php'); class HolidayService { @@ -177,18 +178,24 @@ static function getWeeksFromYear($year = NULL): array return $weeks; } - static function groupByWeeks(array $leavesDetails, $weeks = []): array + static function groupByWeeks(array $leavesDetails, $weeks = [], array $journeyHistories) : array { if (count($leavesDetails) == 0) return []; $dates = array_keys($leavesDetails); $previous_week = date("o\WW", strtotime($dates[0])); $weeks[$previous_week] = $leavesDetails[$dates[0]]['amount'] ?? 1; for ($i = 1; $i < count($dates); $i++) { + $currentJourney= array_filter($journeyHistories, fn($history) => $history->dateBelongsToHistory(date_create($dates[$i])))[0]; + $journey = $currentJourney->getJourney() ?? \ConfigurationParametersManager::getParameter('STANDARD_WORKING_DAY'); $current_week = date("o\WW", strtotime($dates[$i])); if ($current_week == $previous_week) { - $weeks[$current_week] += $leavesDetails[$dates[$i]]['amount'] ?? 1; + $leaveInDays = ($leavesDetails[$dates[$i]]['end'] - $leavesDetails[$dates[$i]]['init']) / 60; + $leavePerDayBasedOnJourney = $leaveInDays / $journey; + $weeks[$current_week] += $leavePerDayBasedOnJourney ?? 1; } else { - $weeks[$current_week] = $leavesDetails[$dates[$i]]['amount'] ?? 1; + $leaveInDays = ($leavesDetails[$dates[$i]]['end'] - $leavesDetails[$dates[$i]]['init']) / 60; + $leavePerDayBasedOnJourney = $leaveInDays / $journey; + $weeks[$current_week] = $leavePerDayBasedOnJourney ?? 1; $previous_week = $current_week; } $weeks[$current_week] = round($weeks[$current_week], 2); @@ -250,10 +257,16 @@ public function getUserVacationsRanges(string $init = NULL, string $end = NULL, $vacations = \UsersFacade::GetScheduledHolidays($init, $end, $userVO); $vacations = $this::mapHalfLeaves($vacations, $journeyHistories); + for ($i = 1; $i < count($vacations); $i++){ + $currentJourney = array_filter($journeyHistories, fn($history) => $history->dateBelongsToHistory(date_create($vacations[$i])))[0]; + } + + $journey = $currentJourney->getJourney() ?? \ConfigurationParametersManager::getParameter('STANDARD_WORKING_DAY'); return [ 'dates' => $vacations, 'ranges' => $this->datesToRanges(array_keys($vacations)), - 'weeks' => $this->groupByWeeks($vacations) + 'weeks' => $this->groupByWeeks($vacations, [], $journeyHistories), + 'journey' => $journey ]; } From c04ee100abf2e673d03222b080e79a31e4fee92e Mon Sep 17 00:00:00 2001 From: Danielle Mayabb Date: Tue, 30 May 2023 13:06:57 -0700 Subject: [PATCH 2/2] Fix existing unit tests and add one for excess leave --- .../unit/web/services/HolidayServiceTest.php | 56 ++++++++++++++++++- web/services/HolidayService.php | 4 +- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/tests/unit/web/services/HolidayServiceTest.php b/tests/unit/web/services/HolidayServiceTest.php index 9476cb45b..615f216d4 100644 --- a/tests/unit/web/services/HolidayServiceTest.php +++ b/tests/unit/web/services/HolidayServiceTest.php @@ -171,13 +171,19 @@ public function testGroupByWeeksSameYear(): void "end" => 420, ] ]; + $journey = new JourneyHistoryVO(); + $journey->setInitDate(DateTime::createFromFormat('Y-m-d', '2021-01-01')); + $journey->setEndDate(DateTime::createFromFormat('Y-m-d', '2021-12-31')); + $journey->setJourney(7.0); + $journeyHistories[] = array(); + $journeyHistories[0] = $journey; $result = [ '2021W41' => 2, '2021W44' => 1 ]; $this->assertEquals( $result, - $this->instance::groupByWeeks($dates) + $this->instance::groupByWeeks($dates, $journeyHistories) ); } @@ -198,13 +204,51 @@ public function testGroupByWeeksWithPartialLeaves(): void "end" => 420, ] ]; + $journey = new JourneyHistoryVO(); + $journey->setInitDate(DateTime::createFromFormat('Y-m-d', '2021-01-01')); + $journey->setEndDate(DateTime::createFromFormat('Y-m-d', '2021-12-31')); + $journey->setJourney(7.0); + $journeyHistories[] = array(); + $journeyHistories[0] = $journey; $result = [ '2021W41' => 1.5, '2021W44' => 1 ]; $this->assertEquals( $result, - $this->instance::groupByWeeks($dates) + $this->instance::groupByWeeks($dates, $journeyHistories) + ); + } + + public function testGroupByWeeksWithExtraLeaves(): void + { + $dates = [ + "2021-10-14" => [ + "init" => 0, + "end" => 336, + ], + "2021-10-15" => [ + "init" => 0, + "end" => 336, + ], + "2021-11-01" => [ + "init" => 0, + "end" => 420, + ] + ]; + $journey = new JourneyHistoryVO(); + $journey->setInitDate(DateTime::createFromFormat('Y-m-d', '2021-01-01')); + $journey->setEndDate(DateTime::createFromFormat('Y-m-d', '2021-12-31')); + $journey->setJourney(5.6); + $journeyHistories[] = array(); + $journeyHistories[0] = $journey; + $result = [ + '2021W41' => 2, + '2021W44' => 1.25 + ]; + $this->assertEquals( + $result, + $this->instance::groupByWeeks($dates, $journeyHistories) ); } @@ -230,9 +274,15 @@ public function testGroupByWeeksWithDateInPastYearISOWeek(): void '2020W53' => 2, '2021W44' => 1 ]; + $journey = new JourneyHistoryVO(); + $journey->setInitDate(DateTime::createFromFormat('Y-m-d', '2021-01-01')); + $journey->setEndDate(DateTime::createFromFormat('Y-m-d', '2021-12-31')); + $journey->setJourney(7.0); + $journeyHistories[] = array(); + $journeyHistories[0] = $journey; $this->assertEquals( $result, - $this->instance::groupByWeeks($dates) + $this->instance::groupByWeeks($dates, $journeyHistories) ); } diff --git a/web/services/HolidayService.php b/web/services/HolidayService.php index 5c9961f29..f438f40fe 100644 --- a/web/services/HolidayService.php +++ b/web/services/HolidayService.php @@ -178,7 +178,7 @@ static function getWeeksFromYear($year = NULL): array return $weeks; } - static function groupByWeeks(array $leavesDetails, $weeks = [], array $journeyHistories) : array + static function groupByWeeks(array $leavesDetails, array $journeyHistories, $weeks = []) : array { if (count($leavesDetails) == 0) return []; $dates = array_keys($leavesDetails); @@ -265,7 +265,7 @@ public function getUserVacationsRanges(string $init = NULL, string $end = NULL, return [ 'dates' => $vacations, 'ranges' => $this->datesToRanges(array_keys($vacations)), - 'weeks' => $this->groupByWeeks($vacations, [], $journeyHistories), + 'weeks' => $this->groupByWeeks($vacations, $journeyHistories), 'journey' => $journey ]; }