Move Shifts helper methods to Shift model
This commit is contained in:
parent
cb82ad9c74
commit
dd096b0f46
|
@ -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,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'],
|
||||||
|
|
|
@ -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'],
|
||||||
|
|
|
@ -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'];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue