Move Shifts helper methods to Shift model

This commit is contained in:
Igor Scheller 2024-04-13 14:27:25 +02:00 committed by xuwhite
parent cb82ad9c74
commit dd096b0f46
9 changed files with 137 additions and 159 deletions

View File

@ -3,7 +3,6 @@
namespace Engelsystem\Events\Listener; namespace Engelsystem\Events\Listener;
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Helpers\Shifts;
use Engelsystem\Mail\EngelsystemMailer; use Engelsystem\Mail\EngelsystemMailer;
use Engelsystem\Models\Shifts\Shift as ShiftModel; use Engelsystem\Models\Shifts\Shift as ShiftModel;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
@ -32,7 +31,7 @@ class Shift
$workLog->worked_at = $shift->start->copy()->startOfDay(); $workLog->worked_at = $shift->start->copy()->startOfDay();
$workLog->hours = $workLog->hours =
(($shift->end->timestamp - $shift->start->timestamp) / 60 / 60) (($shift->end->timestamp - $shift->start->timestamp) / 60 / 60)
* Shifts::getNightShiftMultiplier($shift->start, $shift->end); * $shift->getNightShiftMultiplier();
$workLog->comment = sprintf( $workLog->comment = sprintf(
__('%s (%s as %s) in %s, %s - %s'), __('%s (%s as %s) in %s, %s - %s'),
$shift->shiftType->name, $shift->shiftType->name,

View File

@ -123,7 +123,7 @@ function User_get_shifts_sum_query()
return 'COALESCE(SUM(UNIX_TIMESTAMP(shifts.end) - UNIX_TIMESTAMP(shifts.start)), 0)'; return 'COALESCE(SUM(UNIX_TIMESTAMP(shifts.end) - UNIX_TIMESTAMP(shifts.start)), 0)';
} }
/* @see \Engelsystem\Helpers\Shifts::isNightShift to keep it in sync */ /* @see \Engelsystem\Models\Shifts\Shift::isNightShift to keep it in sync */
return sprintf( return sprintf(
' '
COALESCE(SUM( COALESCE(SUM(

View File

@ -3,7 +3,6 @@
namespace Engelsystem; namespace Engelsystem;
use Engelsystem\Config\GoodieType; use Engelsystem\Config\GoodieType;
use Engelsystem\Helpers\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
@ -245,7 +244,6 @@ class ShiftCalendarShiftRenderer
*/ */
private function renderShiftHead(Shift $shift, $class, $needed_angeltypes_count) private function renderShiftHead(Shift $shift, $class, $needed_angeltypes_count)
{ {
$nightShiftsConfig = config('night_shifts');
$goodie = GoodieType::from(config('goodie_type')); $goodie = GoodieType::from(config('goodie_type'));
$goodie_enabled = $goodie !== GoodieType::None; $goodie_enabled = $goodie !== GoodieType::None;
@ -281,7 +279,7 @@ class ShiftCalendarShiftRenderer
]); ]);
} }
$night_shift = ''; $night_shift = '';
if (Shifts::isNightShift($shift->start, $shift->end) && $nightShiftsConfig['enabled'] && $goodie_enabled) { if ($shift->isNightShift() && $goodie_enabled) {
$night_shift = ' <i class="bi-moon-stars"></i>'; $night_shift = ' <i class="bi-moon-stars"></i>';
} }

View File

@ -2,7 +2,6 @@
use Engelsystem\Config\GoodieType; use Engelsystem\Config\GoodieType;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Helpers\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Location; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
@ -269,7 +268,7 @@ function Shift_view(
$start = $shift->start->format(__('general.datetime')); $start = $shift->start->format(__('general.datetime'));
$night_shift_hint = ''; $night_shift_hint = '';
if (Shifts::isNightShift($shift->start, $shift->end) && $nightShiftsConfig['enabled'] && $goodie_enabled) { if ($shift->isNightShift() && $goodie_enabled) {
$night_shift_hint = ' <small><span class="bi bi-moon-stars text-info" data-bs-toggle="tooltip" title="' $night_shift_hint = ' <small><span class="bi bi-moon-stars text-info" data-bs-toggle="tooltip" title="'
. __('Night shifts between %d and %d am are multiplied by %d for the %s score.', [ . __('Night shifts between %d and %d am are multiplied by %d for the %s score.', [
$nightShiftsConfig['start'], $nightShiftsConfig['start'],

View File

@ -2,7 +2,6 @@
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Config\GoodieType; use Engelsystem\Config\GoodieType;
use Engelsystem\Helpers\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Group; use Engelsystem\Models\Group;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
@ -325,7 +324,7 @@ function User_view_myshift(Shift $shift, $user_source, $its_me)
} }
$night_shift = ''; $night_shift = '';
if (Shifts::isNightShift($shift->start, $shift->end) && $nightShiftsConfig['enabled'] && $goodie_enabled) { if ($shift->isNightShift() && $goodie_enabled) {
$night_shift = ' <span class="bi bi-moon-stars text-info" data-bs-toggle="tooltip" title="' $night_shift = ' <span class="bi bi-moon-stars text-info" data-bs-toggle="tooltip" title="'
. __('Night shifts between %d and %d am are multiplied by %d for the %s score.', [ . __('Night shifts between %d and %d am are multiplied by %d for the %s score.', [
$nightShiftsConfig['start'], $nightShiftsConfig['start'],

View File

@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Helpers;
use Carbon\Carbon;
// Should be moved to the shift model if it's available
class Shifts
{
/**
* Check if a time range is a night shift
*/
public static function isNightShift(Carbon $start, Carbon $end): bool
{
$config = config('night_shifts');
/** @see User_get_shifts_sum_query to keep it in sync */
return $config['enabled'] && (
// Starts during night
$start->hour >= $config['start'] && $start->hour < $config['end']
// Ends during night
|| (
$end->hour > $config['start']
|| $end->hour == $config['start'] && $end->minute > 0
) && $end->hour <= $config['end']
// Starts before and ends after night
|| $start->hour <= $config['start'] && $end->hour >= $config['end']
);
}
/**
* Calculate a shifts night multiplier
*/
public static function getNightShiftMultiplier(Carbon $start, Carbon $end): float
{
if (!self::isNightShift($start, $end)) {
return 1;
}
return config('night_shifts')['multiplier'];
}
}

View File

@ -125,4 +125,37 @@ class Shift extends BaseModel
{ {
return $this->belongsTo(User::class, 'updated_by'); return $this->belongsTo(User::class, 'updated_by');
} }
/**
* Check if the shift is a night shift
*/
public function isNightShift(): bool
{
$config = config('night_shifts');
/** @see User_get_shifts_sum_query to keep it in sync */
return $config['enabled'] && (
// Starts during night
$this->start->hour >= $config['start'] && $this->start->hour < $config['end']
// Ends during night
|| (
$this->end->hour > $config['start']
|| $this->end->hour == $config['start'] && $this->end->minute > 0
) && $this->end->hour <= $config['end']
// Starts before and ends after night
|| $this->start->hour <= $config['start'] && $this->end->hour >= $config['end']
);
}
/**
* Calculate the shifts night multiplier
*/
public function getNightShiftMultiplier(): float
{
if (!$this->isNightShift()) {
return 1;
}
return config('night_shifts')['multiplier'];
}
} }

View File

@ -1,105 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Test\Unit\Helpers;
use Engelsystem\Config\Config;
use Engelsystem\Helpers\Carbon;
use Engelsystem\Helpers\Shifts;
use Engelsystem\Test\Unit\TestCase;
class ShiftsTest extends TestCase
{
/**
* @covers \Engelsystem\Helpers\Shifts::isNightShift
*/
public function testIsNightShiftDisabled(): void
{
$config = new Config(['night_shifts' => [
'enabled' => false,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
// At night but disabled
$this->assertFalse(Shifts::isNightShift(
new Carbon('2042-01-01 04:00'),
new Carbon('2042-01-01 05:00')
));
}
/**
* @return array{0: string, 1: string, 2: boolean}[]
*/
public function nightShiftData(): array
{
// $start, $end, $isNightShift
return [
// Is night shift
['2042-01-01 04:00', '2042-01-01 05:00', true],
// Is night shift
['2042-01-01 02:00', '2042-01-01 02:15', true],
// Is night shift
['2042-01-01 07:45', '2042-01-01 08:00', true],
// Starts as night shift
['2042-01-01 07:59', '2042-01-01 09:00', true],
// Ends as night shift
['2042-01-01 00:00', '2042-01-01 02:01', true],
// Equals night shift
['2042-01-01 02:00', '2042-01-01 08:00', true],
// Contains night shift
['2042-01-01 01:00', '2042-01-01 09:00', true],
// Too early
['2042-01-01 00:00', '2042-01-01 02:00', false],
// Too late
['2042-01-01 08:00', '2042-01-01 10:00', false],
// Out of range
['2042-01-01 23:00', '2042-01-02 01:00', false],
];
}
/**
* @covers \Engelsystem\Helpers\Shifts::isNightShift
* @dataProvider nightShiftData
*/
public function testIsNightShiftEnabled(string $start, string $end, bool $isNightShift): void
{
$config = new Config(['night_shifts' => [
'enabled' => true,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
$this->assertEquals($isNightShift, Shifts::isNightShift(new Carbon($start), new Carbon($end)));
}
/**
* @covers \Engelsystem\Helpers\Shifts::getNightShiftMultiplier
*/
public function testGetNightShiftMultiplier(): void
{
$config = new Config(['night_shifts' => [
'enabled' => true,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
$this->assertEquals(2, Shifts::getNightShiftMultiplier(
new Carbon('2042-01-01 02:00'),
new Carbon('2042-01-01 04:00')
));
$config->set('night_shifts', array_merge($config->get('night_shifts'), ['enabled' => false]));
$this->assertEquals(1, Shifts::getNightShiftMultiplier(
new Carbon('2042-01-01 02:00'),
new Carbon('2042-01-01 04:00')
));
}
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Models\Shifts; namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Config\Config;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\Location; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
@ -111,4 +112,102 @@ class ShiftTest extends ModelTest
$this->assertCount(5, $shift->shiftEntries); $this->assertCount(5, $shift->shiftEntries);
} }
/**
* @covers \Engelsystem\Models\Shifts\Shift::isNightShift
*/
public function testIsNightShiftDisabled(): void
{
$config = new Config(['night_shifts' => [
'enabled' => false,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
$shift = new Shift([
'start' => new Carbon('2042-01-01 04:00'),
'end' => new Carbon('2042-01-01 05:00'),
]);
// At night but disabled
$this->assertFalse($shift->isNightShift());
}
/**
* @return array{0: string, 1: string, 2: boolean}[]
*/
public function nightShiftData(): array
{
// $start, $end, $isNightShift
return [
// Is night shift
['2042-01-01 04:00', '2042-01-01 05:00', true],
// Is night shift
['2042-01-01 02:00', '2042-01-01 02:15', true],
// Is night shift
['2042-01-01 07:45', '2042-01-01 08:00', true],
// Starts as night shift
['2042-01-01 07:59', '2042-01-01 09:00', true],
// Ends as night shift
['2042-01-01 00:00', '2042-01-01 02:01', true],
// Equals night shift
['2042-01-01 02:00', '2042-01-01 08:00', true],
// Contains night shift
['2042-01-01 01:00', '2042-01-01 09:00', true],
// Too early
['2042-01-01 00:00', '2042-01-01 02:00', false],
// Too late
['2042-01-01 08:00', '2042-01-01 10:00', false],
// Out of range
['2042-01-01 23:00', '2042-01-02 01:00', false],
];
}
/**
* @covers \Engelsystem\Models\Shifts\Shift::isNightShift
* @dataProvider nightShiftData
*/
public function testIsNightShiftEnabled(string $start, string $end, bool $isNightShift): void
{
$config = new Config(['night_shifts' => [
'enabled' => true,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
$shift = new Shift([
'start' => new Carbon($start),
'end' => new Carbon($end),
]);
$this->assertEquals($isNightShift, $shift->isNightShift());
}
/**
* @covers \Engelsystem\Models\Shifts\Shift::getNightShiftMultiplier
*/
public function testGetNightShiftMultiplier(): void
{
$config = new Config(['night_shifts' => [
'enabled' => true,
'start' => 2,
'end' => 8,
'multiplier' => 2,
]]);
$this->app->instance('config', $config);
$shift = new Shift([
'start' => new Carbon('2042-01-01 02:00'),
'end' => new Carbon('2042-01-01 04:00'),
]);
$this->assertEquals(2, $shift->getNightShiftMultiplier());
$config->set('night_shifts', array_merge($config->get('night_shifts'), ['enabled' => false]));
$this->assertEquals(1, $shift->getNightShiftMultiplier());
}
} }