Skip to content
This repository has been archived by the owner on Sep 9, 2019. It is now read-only.

Commit

Permalink
Replaced legacy MissionDaysCalculator with new ones
Browse files Browse the repository at this point in the history
Related to #147 as well as #78.
  • Loading branch information
andyundso committed Jan 17, 2019
1 parent f6efb66 commit e83741c
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 152 deletions.
36 changes: 36 additions & 0 deletions api/app/Http/Controllers/api/MissionDayController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Services\Calculator\MissionDaysCalculator;
use Carbon\Carbon;
use Illuminate\Http\Request;

class MissionDayController extends Controller
{
public function eligibleDays(Request $request)
{
$validatedData = $this->validate($request, [
'end' => 'required|date',
'start' => 'required|date'
]);

$carbonizedStart = Carbon::parse($validatedData['start']);
$carbonizedEnd = Carbon::parse($validatedData['end']);

return MissionDaysCalculator::calculateEligibleDays($carbonizedStart, $carbonizedEnd);
}

public function possibleEndDate(Request $request)
{
$validatedData = $this->validate($request, [
'days' => 'required|integer',
'start' => 'required|date'
]);

$carbonizedStart = Carbon::parse($validatedData['start']);

return MissionDaysCalculator::calculatePossibleEndDate($carbonizedStart, $validatedData['days'])->format('Y-m-d');
}
}
7 changes: 4 additions & 3 deletions api/app/Http/Controllers/api/ReportSheetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Http\Controllers\Controller;
use App\ReportSheet;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

Expand Down Expand Up @@ -31,9 +32,9 @@ public function index()
->get();

// Add calculated column days
foreach ($reportSheets as $reportSheet) {
$reportSheet['days'] = ReportSheet::getDiensttageCount($reportSheet->start, $reportSheet->end);
}
$reportSheets->each(function ($r) {
$r->append('duration');
});

return $reportSheets;
} else {
Expand Down
131 changes: 0 additions & 131 deletions api/app/ReportSheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,137 +125,6 @@ public function getWorkFreeDaysCostsAttribute()
return $this->mission->specification->daily_spare_time_costs * ($this->workfree + $this->additional_workfree);
}

private static function countDaysBetween($start_TS, $end_TS)
{
if ($start_TS > $end_TS) {
$tmp = $start_TS;
$start_TS = $end_TS;
$end_TS = $tmp;
}
$d = date("d", $start_TS);
$m = date("m", $start_TS);
$y = date("Y", $start_TS);
$c = 0;
$found = false;
while (!$found) {
if (mktime(0, 0, 0, $m, $d + $c, $y) == $end_TS) {
$found = true;
$c++;
} else {
$c++;
}
if ($c > 26000) {
$c = 0;
break;
}
}
return $c;
}

private static function tomorrow($day_TS)
{
$d = date("j", $day_TS);
$m = date("m", $day_TS);
$y = date("Y", $day_TS);
return mktime(0, 0, 0, $m, $d + 1, $y);
}

public static function getDiensttageCount($start, $end, $long_mission = false)
{
if (strtotime($end)>=strtotime($start)) {
$dayCount = ReportSheet::countDaysBetween(strtotime($start), strtotime($end));
return ReportSheet::subtractFreeDays($start, $end, $dayCount, $long_mission);
} else {
return 0;
}
}

public static function getDiensttageEndDate($start, $days, $long_mission)
{

$end = $start;
if (isset($days) && $days > 0) {
// end date is usually start date + days
$end = ReportSheet::addDaysToDate($start, $days-1);
$lastEnd = $end;
$chargedDays = -2;
$hasHolidays = false;

// the end date is increased until the charged days matches the selection (in case there are holidays)
while ($chargedDays < $days && $chargedDays < 400) {
$lastEnd = $end;
$end = ReportSheet::addDaysToDate($end, 1);
$chargedDays = ReportSheet::getDiensttageCount($start, $end, $long_mission);

if ($chargedDays < $days+1) {
$hasHolidays = true;
}
}
}

// if there are holidays found, the date needs to be set to the next day
if ($hasHolidays) {
return $end;
}

return $lastEnd;
}

/**
* Subtracts the number of days that are "Betriebsferien" and not "Feiertage"
*/
private static function subtractFreeDays($start, $end, $dayCount, $long_mission)
{
$ziviHolidays = MissionController::calculateZiviHolidays($long_mission, $dayCount);

$betriebsferien = Holiday::join('holiday_types', 'holidays.holiday_type_id', '=', 'holiday_types.id')
->whereDate('date_from', '<=', $end)
->whereDate('date_to', '>=', $start)
->where('holiday_types.name', '=', 'Betriebsferien')
->get();

$feiertage = Holiday::join('holiday_types', 'holidays.holiday_type_id', '=', 'holiday_types.id')
->whereDate('date_from', '<=', $end)
->whereDate('date_to', '>=', $start)
->where('holiday_types.name', '=', 'Feiertag')
->get();

foreach ($betriebsferien as $ferien) {
for ($u = max(strtotime($start), strtotime($ferien['date_from'])); $u<=min(strtotime($end), strtotime($ferien['date_to'])); $u=ReportSheet::tomorrow($u)) {
if (date('w', $u)==0 || date('w', $u)==6) {
//ingore saturday & sunday, because they count as Diensttag anyway
} else {
$isInFeiertag = false;
foreach ($feiertage as $feiertag) {
if (strtotime($feiertag['date_from'])<=$u && $u<=strtotime($feiertag['date_to'])) {
$isInFeiertag = true;
break;
}
}
if (!$isInFeiertag) {
if ($ziviHolidays > 0) {
$ziviHolidays--;
} else {
$dayCount--;
}
}
}
}
}

return $dayCount;
}

/**
* Returns the calculated date as a string
*/
private static function addDaysToDate($dateString, $days)
{
$datetime = DateTime::createFromFormat('Y-m-d', $dateString);
$datetime->modify('+'.$days.' day');
return $datetime->format('Y-m-d');
}

// Delete all linked report sheets to a mission when a mission is soft deleted
public static function deleteByMission($missionId)
{
Expand Down
23 changes: 5 additions & 18 deletions api/routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
$router->post('/', ['uses' => 'MissionController@post']);
});

$router->group(['prefix' => 'mission_days'], function () use ($router) {
$router->get('/eligible_days', ['uses' => 'MissionDayController@eligibleDays']);
$router->get('/possible_end_date', ['uses' => 'MissionDayController@possibleEndDate']);
});

$router->group(['prefix' => 'regional_centers'], function () use ($router) {
$router->get('/', ['uses' => 'RegionalCenterController@index']);
});
Expand Down Expand Up @@ -66,24 +71,6 @@
$router->get('/', ['uses' => 'FeedbackController@index']);
});

// TODO Hook diensttage and diensttageEnd into separate CalcController (from #78)
// Service days - Authenticated
$router->get('/diensttage', function () {
$start = Input::get("start", "");
$end = Input::get("end", "");
$long_mission = Input::get("long_mission", false);

return response()->json(ReportSheet::getDiensttageCount($start, $end, $long_mission));
});

$router->get('/diensttageEndDate', function () {
$start = Input::get("start", "");
$days = Input::get("days", "0");
$long_mission = Input::get("long_mission", false);

return response()->json(ReportSheet::getDiensttageEndDate($start, $days, $long_mission));
});

// Admins only
$router->group(['middleware' => 'role'], function ($router) {
/** @var Router $router */
Expand Down
36 changes: 36 additions & 0 deletions api/tests/integrations/MissionDayControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Tests\Integration;

class MissionDayControllerTest extends \TestCase
{
public function testInvalidEligibleDays()
{
$this->asUser()->json('GET', 'api/mission_days/eligible_days')->assertResponseStatus(422);
}

public function testValidEligibleDays()
{
$this->asUser()->json('GET', 'api/mission_days/eligible_days', [
'start' => '2019-01-01',
'end' => '2019-01-31'
])->assertResponseOk();

$this->assertEquals(31, $this->response->getContent());
}

public function testInvalidEndDate()
{
$this->asUser()->json('GET', 'api/mission_days/possible_end_date')->assertResponseStatus(422);
}

public function testValidEndDate()
{
$this->asUser()->json('GET', 'api/mission_days/possible_end_date', [
'start' => '2019-01-01',
'days' => '31'
])->assertResponseOk();

$this->assertEquals('2019-01-31', $this->response->getContent());
}
}

0 comments on commit e83741c

Please sign in to comment.