Replaced ShiftTypes with shift_types / ShiftType model

This commit is contained in:
Igor Scheller 2022-11-08 00:33:42 +01:00
parent ac162f4411
commit 992e708276
18 changed files with 382 additions and 274 deletions

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\Shifts\ShiftType;
use Illuminate\Database\Eloquent\Factories\Factory;
class ShiftTypeFactory extends Factory
{
/** @var string */
protected $model = ShiftType::class;
/**
* @return array
*/
public function definition(): array
{
return [
'name' => $this->faker->unique()->firstName(),
'description' => $this->faker->text(),
];
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateShiftTypesTable extends Migration
{
use ChangesReferences;
/**
* Creates the new table, copies the data and drops the old one
*/
public function up(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('shift_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->text('description');
});
if (!$this->schema->hasTable('ShiftTypes')) {
return;
}
/** @var stdClass[] $records */
$records = $connection
->table('ShiftTypes')
->get();
foreach ($records as $record) {
$connection->table('shift_types')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
]);
}
$this->changeReferences(
'ShiftTypes',
'id',
'shift_types',
'id'
);
$this->schema->drop('ShiftTypes');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('ShiftTypes', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 255);
$table->mediumText('description');
});
/** @var stdClass[] $records */
$records = $connection
->table('shift_types')
->get();
foreach ($records as $record) {
$connection->table('ShiftTypes')->insert([
'id' => $record->id,
'name' => $record->name,
'description' => $record->description,
]);
}
$this->changeReferences(
'shift_types',
'id',
'ShiftTypes',
'id'
);
$this->schema->drop('shift_types');
}
}

View File

@ -1,6 +1,7 @@
<?php <?php
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
/** /**
@ -69,7 +70,7 @@ function public_dashboard_controller()
*/ */
function public_dashboard_controller_free_shift($shift, ShiftsFilter $filter = null) function public_dashboard_controller_free_shift($shift, ShiftsFilter $filter = null)
{ {
$shifttype = ShiftType($shift['shifttype_id']); $shifttype = ShiftType::find($shift['shifttype_id']);
$room = Room::find($shift['RID']); $room = Room::find($shift['RID']);
$free_shift = [ $free_shift = [
@ -78,7 +79,7 @@ function public_dashboard_controller_free_shift($shift, ShiftsFilter $filter = n
'start' => date('H:i', $shift['start']), 'start' => date('H:i', $shift['start']),
'end' => date('H:i', $shift['end']), 'end' => date('H:i', $shift['end']),
'duration' => round(($shift['end'] - $shift['start']) / 3600), 'duration' => round(($shift['end'] - $shift['start']) / 3600),
'shifttype_name' => $shifttype['name'], 'shifttype_name' => $shifttype->name,
'title' => $shift['title'], 'title' => $shift['title'],
'room_name' => $room->name, 'room_name' => $room->name,
'needed_angels' => public_dashboard_needed_angels($shift['NeedAngels'], $filter), 'needed_angels' => public_dashboard_needed_angels($shift['NeedAngels'], $filter),

View File

@ -4,6 +4,7 @@ use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\Exceptions\HttpForbidden; use Engelsystem\Http\Exceptions\HttpForbidden;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ScheduleShift; use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
@ -70,7 +71,7 @@ function shift_edit_controller()
$rooms[$room->id] = $room->name; $rooms[$room->id] = $room->name;
} }
$angeltypes = select_array(AngelTypes(), 'id', 'name'); $angeltypes = select_array(AngelTypes(), 'id', 'name');
$shifttypes = select_array(ShiftTypes(), 'id', 'name'); $shifttypes = select_array(ShiftType::all(), 'id', 'name');
$needed_angel_types = select_array( $needed_angel_types = select_array(
NeededAngelTypes_by_shift($shift_id), NeededAngelTypes_by_shift($shift_id),
@ -301,7 +302,7 @@ function shift_controller()
throw_redirect(page_link_to('user_shifts')); throw_redirect(page_link_to('user_shifts'));
} }
$shifttype = ShiftType($shift['shifttype_id']); $shifttype = ShiftType::find($shift['shifttype_id']);
$room = Room::find($shift['RID']); $room = Room::find($shift['RID']);
$angeltypes = AngelTypes(); $angeltypes = AngelTypes();
$user_shifts = Shifts_by_user($user->id); $user_shifts = Shifts_by_user($user->id);

View File

@ -1,12 +1,14 @@
<?php <?php
use Engelsystem\Models\Shifts\ShiftType;
/** /**
* @param array $shifttype * @param ShiftType $shifttype
* @return string * @return string
*/ */
function shifttype_link($shifttype) function shifttype_link(ShiftType $shifttype)
{ {
return page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype['id']]); return page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id]);
} }
/** /**
@ -21,21 +23,17 @@ function shifttype_delete_controller()
throw_redirect(page_link_to('shifttypes')); throw_redirect(page_link_to('shifttypes'));
} }
$shifttype = ShiftType($request->input('shifttype_id')); $shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
if (empty($shifttype)) {
throw_redirect(page_link_to('shifttypes'));
}
if ($request->hasPostData('delete')) { if ($request->hasPostData('delete')) {
ShiftType_delete($shifttype['id']); engelsystem_log('Deleted shifttype ' . $shifttype->name);
success(sprintf(__('Shifttype %s deleted.'), $shifttype->name));
engelsystem_log('Deleted shifttype ' . $shifttype['name']); $shifttype->delete();
success(sprintf(__('Shifttype %s deleted.'), $shifttype['name']));
throw_redirect(page_link_to('shifttypes')); throw_redirect(page_link_to('shifttypes'));
} }
return [ return [
sprintf(__('Delete shifttype %s'), $shifttype['name']), sprintf(__('Delete shifttype %s'), $shifttype->name),
ShiftType_delete_view($shifttype) ShiftType_delete_view($shifttype)
]; ];
} }
@ -54,14 +52,10 @@ function shifttype_edit_controller()
$request = request(); $request = request();
if ($request->has('shifttype_id')) { if ($request->has('shifttype_id')) {
$shifttype = ShiftType($request->input('shifttype_id')); $shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
if (empty($shifttype)) { $shifttype_id = $shifttype->id;
error(__('Shifttype not found.')); $name = $shifttype->name;
throw_redirect(page_link_to('shifttypes')); $description = $shifttype->description;
}
$shifttype_id = $shifttype['id'];
$name = $shifttype['name'];
$description = $shifttype['description'];
} }
if ($request->hasPostData('submit')) { if ($request->hasPostData('submit')) {
@ -79,17 +73,21 @@ function shifttype_edit_controller()
} }
if ($valid) { if ($valid) {
if ($shifttype_id) { $shiftType = ShiftType::findOrNew($shifttype_id);
ShiftType_update($shifttype_id, $name, $description); $shiftType->name = $name;
$shiftType->description = $description;
$shiftType->save();
if ($shifttype_id) {
engelsystem_log('Updated shifttype ' . $name); engelsystem_log('Updated shifttype ' . $name);
success(__('Updated shifttype.')); success(__('Updated shifttype.'));
} else { } else {
$shifttype_id = ShiftType_create($name, $description); $shifttype_id = $shiftType->id;
engelsystem_log('Created shifttype ' . $name); engelsystem_log('Created shifttype ' . $name);
success(__('Created shifttype.')); success(__('Created shifttype.'));
} }
throw_redirect(page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype_id])); throw_redirect(page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype_id]));
} }
} }
@ -109,13 +107,10 @@ function shifttype_controller()
if (!$request->has('shifttype_id')) { if (!$request->has('shifttype_id')) {
throw_redirect(page_link_to('shifttypes')); throw_redirect(page_link_to('shifttypes'));
} }
$shifttype = ShiftType($request->input('shifttype_id')); $shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
if (empty($shifttype)) {
throw_redirect(page_link_to('shifttypes'));
}
return [ return [
$shifttype['name'], $shifttype->name,
ShiftType_view($shifttype) ShiftType_view($shifttype)
]; ];
} }
@ -127,7 +122,7 @@ function shifttype_controller()
*/ */
function shifttypes_list_controller() function shifttypes_list_controller()
{ {
$shifttypes = ShiftTypes(); $shifttypes = ShiftType::all();
return [ return [
shifttypes_title(), shifttypes_title(),

View File

@ -18,7 +18,6 @@ $includeFiles = [
__DIR__ . '/../includes/model/Shifts_model.php', __DIR__ . '/../includes/model/Shifts_model.php',
__DIR__ . '/../includes/model/ShiftsFilter.php', __DIR__ . '/../includes/model/ShiftsFilter.php',
__DIR__ . '/../includes/model/ShiftSignupState.php', __DIR__ . '/../includes/model/ShiftSignupState.php',
__DIR__ . '/../includes/model/ShiftTypes_model.php',
__DIR__ . '/../includes/model/Stats.php', __DIR__ . '/../includes/model/Stats.php',
__DIR__ . '/../includes/model/UserAngelTypes_model.php', __DIR__ . '/../includes/model/UserAngelTypes_model.php',
__DIR__ . '/../includes/model/User_model.php', __DIR__ . '/../includes/model/User_model.php',

View File

@ -3,6 +3,7 @@
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Database\Db; use Engelsystem\Database\Db;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
/** /**
@ -58,7 +59,7 @@ function ShiftEntry_create($shift_entry)
{ {
$user = User::find($shift_entry['UID']); $user = User::find($shift_entry['UID']);
$shift = Shift($shift_entry['SID']); $shift = Shift($shift_entry['SID']);
$shifttype = ShiftType($shift['shifttype_id']); $shifttype = ShiftType::find($shift['shifttype_id']);
$room = Room::find($shift['RID']); $room = Room::find($shift['RID']);
$angeltype = AngelType($shift_entry['TID']); $angeltype = AngelType($shift_entry['TID']);
$result = Db::insert( $result = Db::insert(
@ -85,7 +86,7 @@ function ShiftEntry_create($shift_entry)
engelsystem_log( engelsystem_log(
'User ' . User_Nick_render($user, true) 'User ' . User_Nick_render($user, true)
. ' signed up for shift ' . $shift['name'] . ' signed up for shift ' . $shift['name']
. ' (' . $shifttype['name'] . ')' . ' (' . $shifttype->name . ')'
. ' at ' . $room->name . ' at ' . $room->name
. ' from ' . date('Y-m-d H:i', $shift['start']) . ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end']) . ' to ' . date('Y-m-d H:i', $shift['end'])
@ -145,14 +146,14 @@ function ShiftEntry_delete($shiftEntry)
$signout_user = User::find($shiftEntry['UID']); $signout_user = User::find($shiftEntry['UID']);
$shift = Shift($shiftEntry['SID']); $shift = Shift($shiftEntry['SID']);
$shifttype = ShiftType($shift['shifttype_id']); $shifttype = ShiftType::find($shift['shifttype_id']);
$room = Room::find($shift['RID']); $room = Room::find($shift['RID']);
$angeltype = AngelType($shiftEntry['TID']); $angeltype = AngelType($shiftEntry['TID']);
engelsystem_log( engelsystem_log(
'Shift signout: ' . User_Nick_render($signout_user, true) 'Shift signout: ' . User_Nick_render($signout_user, true)
. ' from shift ' . $shift['name'] . ' from shift ' . $shift['name']
. ' (' . $shifttype['name'] . ')' . ' (' . $shifttype->name . ')'
. ' at ' . $room->name . ' at ' . $room->name
. ' from ' . date('Y-m-d H:i', $shift['start']) . ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end']) . ' to ' . date('Y-m-d H:i', $shift['end'])
@ -175,7 +176,7 @@ function ShiftEntries_upcoming_for_user($userId)
SELECT * SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`) JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
WHERE `ShiftEntry`.`UID` = ? WHERE `ShiftEntry`.`UID` = ?
AND `Shifts`.`end` > ? AND `Shifts`.`end` > ?
ORDER BY `Shifts`.`end` ORDER BY `Shifts`.`end`
@ -201,7 +202,7 @@ function ShiftEntries_finished_by_user($userId, Carbon $sinceTime = null)
SELECT * SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`) JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
WHERE `ShiftEntry`.`UID` = ? WHERE `ShiftEntry`.`UID` = ?
AND `Shifts`.`end` < ? AND `Shifts`.`end` < ?
AND `ShiftEntry`.`freeloaded` = 0 AND `ShiftEntry`.`freeloaded` = 0

View File

@ -1,83 +0,0 @@
<?php
use Engelsystem\Database\Db;
/**
* Delete a shift type.
*
* @param int $shifttype_id
*/
function ShiftType_delete($shifttype_id)
{
Db::delete('DELETE FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]);
}
/**
* Update a shift type.
*
* @param int $shifttype_id
* @param string $name
* @param string $description
*/
function ShiftType_update($shifttype_id, $name, $description)
{
Db::update(
'
UPDATE `ShiftTypes` SET
`name`=?,
`description`=?
WHERE `id`=?
',
[
$name,
$description,
$shifttype_id,
]
);
}
/**
* Create a shift type.
*
* @param string $name
* @param string $description
* @return int|false new shifttype id
*/
function ShiftType_create($name, $description)
{
Db::insert(
'
INSERT INTO `ShiftTypes` (`name`, `description`)
VALUES(?, ?)
',
[
$name,
$description
]
);
return Db::getPdo()->lastInsertId();
}
/**
* Get a shift type by id.
*
* @param int $shifttype_id
* @return array|null
*/
function ShiftType($shifttype_id)
{
$shiftType = Db::selectOne('SELECT * FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]);
return empty($shiftType) ? null : $shiftType;
}
/**
* Get all shift types.
*
* @return array[]
*/
function ShiftTypes()
{
return Db::select('SELECT * FROM `ShiftTypes` ORDER BY `name`');
}

View File

@ -2,6 +2,7 @@
use Engelsystem\Database\Db; use Engelsystem\Database\Db;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
@ -98,10 +99,10 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{ {
$sql = ' $sql = '
SELECT * FROM ( SELECT * FROM (
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `rooms`.`name` AS `room_name` SELECT DISTINCT `Shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
FROM `Shifts` FROM `Shifts`
JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id` JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id`
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
@ -112,10 +113,10 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
UNION UNION
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `rooms`.`name` AS `room_name` SELECT DISTINCT `Shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
FROM `Shifts` FROM `Shifts`
JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id` JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id`
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
@ -526,7 +527,7 @@ function Shift_delete($shift_id)
function Shift_update($shift) function Shift_update($shift)
{ {
$user = auth()->user(); $user = auth()->user();
$shift['name'] = ShiftType($shift['shifttype_id'])['name']; $shift['name'] = ShiftType::find($shift['shifttype_id'])->name;
mail_shift_change(Shift($shift['SID']), $shift); mail_shift_change(Shift($shift['SID']), $shift);
return Db::update( return Db::update(
@ -616,8 +617,8 @@ function Shifts_by_user($userId, $include_freeload_comments = false)
SELECT SELECT
`rooms`.*, `rooms`.*,
`rooms`.name AS Name, `rooms`.name AS Name,
`ShiftTypes`.`id` AS `shifttype_id`, `shift_types`.`id` AS `shifttype_id`,
`ShiftTypes`.`name`, `shift_types`.`name`,
`ShiftEntry`.`id`, `ShiftEntry`.`id`,
`ShiftEntry`.`SID`, `ShiftEntry`.`SID`,
`ShiftEntry`.`TID`, `ShiftEntry`.`TID`,
@ -630,7 +631,7 @@ function Shifts_by_user($userId, $include_freeload_comments = false)
? AS event_timezone ? AS event_timezone
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`) JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`) JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`)
WHERE `UID` = ? WHERE `UID` = ?
ORDER BY `start` ORDER BY `start`
@ -651,9 +652,9 @@ function Shifts_by_user($userId, $include_freeload_comments = false)
function Shift($shift_id) function Shift($shift_id)
{ {
$result = Db::selectOne(' $result = Db::selectOne('
SELECT `Shifts`.*, `ShiftTypes`.`name` SELECT `Shifts`.*, `shift_types`.`name`
FROM `Shifts` FROM `Shifts`
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
WHERE `SID`=?', [$shift_id]); WHERE `SID`=?', [$shift_id]);
if (empty($result)) { if (empty($result)) {

View File

@ -4,6 +4,7 @@ use Engelsystem\Database\Db;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\Exceptions\HttpForbidden; use Engelsystem\Http\Exceptions\HttpForbidden;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -52,15 +53,15 @@ function admin_shifts()
} }
// Load shift types // Load shift types
$shifttypes_source = ShiftTypes(); $shifttypes_source = ShiftType::all();
$shifttypes = []; $shifttypes = [];
foreach ($shifttypes_source as $shifttype) { foreach ($shifttypes_source as $shifttype) {
$shifttypes[$shifttype['id']] = $shifttype['name']; $shifttypes[$shifttype->id] = $shifttype->name;
} }
if ($request->has('preview') || $request->has('back')) { if ($request->has('preview') || $request->has('back')) {
if ($request->has('shifttype_id')) { if ($request->has('shifttype_id')) {
$shifttype = ShiftType($request->input('shifttype_id')); $shifttype = ShiftType::find($request->input('shifttype_id'));
if (empty($shifttype)) { if (empty($shifttype)) {
$valid = false; $valid = false;
error(__('Please select a shift type.')); error(__('Please select a shift type.'));
@ -205,9 +206,9 @@ function admin_shifts()
'description' => $description, 'description' => $description,
]; ];
} elseif ($mode == 'multi') { } elseif ($mode == 'multi') {
$shift_start = (int) $start; $shift_start = (int)$start;
do { do {
$shift_end = $shift_start + (int) $length * 60; $shift_end = $shift_start + (int)$length * 60;
if ($shift_end > $end) { if ($shift_end > $end) {
$shift_end = $end; $shift_end = $end;
@ -312,7 +313,7 @@ function admin_shifts()
. '<br />' . '<br />'
. Room_name_render(Room::find($shift['RID'])), . Room_name_render(Room::find($shift['RID'])),
'title' => 'title' =>
ShiftType_name_render(ShiftType($shifttype_id)) ShiftType_name_render(ShiftType::find($shifttype_id))
. ($shift['title'] ? '<br />' . $shift['title'] : ''), . ($shift['title'] ? '<br />' . $shift['title'] : ''),
'needed_angels' => '' 'needed_angels' => ''
]; ];
@ -421,7 +422,8 @@ function admin_shifts()
} }
$angel_types = ''; $angel_types = '';
foreach ($types as $type) { foreach ($types as $type) {
$angel_types .= '<div class="col-md-4">' . form_spinner( $angel_types .= '<div class="col-md-4">'
. form_spinner(
'type_' . $type['id'], 'type_' . $type['id'],
$type['name'], $type['name'],
$needed_angel_types[$type['id']] $needed_angel_types[$type['id']]

View File

@ -17,6 +17,7 @@ use Engelsystem\Http\Response;
use Engelsystem\Models\Room as RoomModel; use Engelsystem\Models\Room as RoomModel;
use Engelsystem\Models\Shifts\Schedule as ScheduleUrl; use Engelsystem\Models\Shifts\Schedule as ScheduleUrl;
use Engelsystem\Models\Shifts\ScheduleShift; use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use ErrorException; use ErrorException;
use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Client as GuzzleClient;
@ -109,7 +110,7 @@ class ImportSchedule extends BaseController
'admin/schedule/edit.twig', 'admin/schedule/edit.twig',
[ [
'schedule' => $schedule, 'schedule' => $schedule,
'shift_types' => $this->getShiftTypes(), 'shift_types' => ShiftType::all()->pluck('name', 'id'),
] + $this->getNotifications() ] + $this->getNotifications()
); );
} }
@ -133,7 +134,7 @@ class ImportSchedule extends BaseController
'minutes_after' => 'int', 'minutes_after' => 'int',
]); ]);
if (!isset($this->getShiftTypes()[$data['shift_type']])) { if (!ShiftType::find($data['shift_type'])) {
throw new ErrorException('schedule.import.invalid-shift-type'); throw new ErrorException('schedule.import.invalid-shift-type');
} }
@ -299,14 +300,14 @@ class ImportSchedule extends BaseController
$shiftEntries = $this->db $shiftEntries = $this->db
->table('ShiftEntry') ->table('ShiftEntry')
->select([ ->select([
'ShiftTypes.name', 'Shifts.title', 'AngelTypes.name AS type', 'rooms.id AS room_id', 'shift_types.name', 'Shifts.title', 'AngelTypes.name AS type', 'rooms.id AS room_id',
'Shifts.start', 'Shifts.end', 'ShiftEntry.UID as user_id', 'ShiftEntry.freeloaded' 'Shifts.start', 'Shifts.end', 'ShiftEntry.UID as user_id', 'ShiftEntry.freeloaded'
]) ])
->join('Shifts', 'Shifts.SID', 'ShiftEntry.SID') ->join('Shifts', 'Shifts.SID', 'ShiftEntry.SID')
->join('schedule_shift', 'Shifts.SID', 'schedule_shift.shift_id') ->join('schedule_shift', 'Shifts.SID', 'schedule_shift.shift_id')
->join('rooms', 'rooms.id', 'Shifts.RID') ->join('rooms', 'rooms.id', 'Shifts.RID')
->join('AngelTypes', 'AngelTypes.id', 'ShiftEntry.TID') ->join('AngelTypes', 'AngelTypes.id', 'ShiftEntry.TID')
->join('ShiftTypes', 'ShiftTypes.id', 'Shifts.shifttype_id') ->join('shift_types', 'shift_types.id', 'Shifts.shifttype_id')
->where('schedule_shift.guid', $event->getGuid()) ->where('schedule_shift.guid', $event->getGuid())
->get(); ->get();
@ -639,22 +640,6 @@ class ImportSchedule extends BaseController
); );
} }
/**
* @return string[]
*/
protected function getShiftTypes()
{
$return = [];
/** @var stdClass[] $shiftTypes */
$shiftTypes = $this->db->select('SELECT t.id, t.name FROM ShiftTypes AS t');
foreach ($shiftTypes as $shiftType) {
$return[$shiftType->id] = $shiftType->name;
}
return $return;
}
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context

View File

@ -55,14 +55,14 @@ function user_myshifts()
`ShiftEntry`.`freeload_comment`, `ShiftEntry`.`freeload_comment`,
`ShiftEntry`.`Comment`, `ShiftEntry`.`Comment`,
`ShiftEntry`.`UID`, `ShiftEntry`.`UID`,
`ShiftTypes`.`name`, `shift_types`.`name`,
`Shifts`.*, `Shifts`.*,
`rooms`.`name` as room_name, `rooms`.`name` as room_name,
`AngelTypes`.`name` AS `angel_type` `AngelTypes`.`name` AS `angel_type`
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`) JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`)
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`) JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`) JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`)
WHERE `ShiftEntry`.`id`=? WHERE `ShiftEntry`.`id`=?
AND `UID`=? AND `UID`=?

View File

@ -1,25 +1,28 @@
<?php <?php
use Engelsystem\Models\Shifts\ShiftType;
use Illuminate\Support\Collection;
/** /**
* @param array $shifttype * @param ShiftType $shifttype
* @return string * @return string
*/ */
function ShiftType_name_render($shifttype) function ShiftType_name_render(ShiftType $shifttype)
{ {
if (auth()->can('shifttypes')) { if (auth()->can('shifttypes')) {
return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype['name'] . '</a>'; return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype->name . '</a>';
} }
return $shifttype['name']; return $shifttype->name;
} }
/** /**
* @param array $shifttype * @param ShiftType $shifttype
* @return string * @return string
*/ */
function ShiftType_delete_view($shifttype) function ShiftType_delete_view(ShiftType $shifttype)
{ {
return page_with_title(sprintf(__('Delete shifttype %s'), $shifttype['name']), [ return page_with_title(sprintf(__('Delete shifttype %s'), $shifttype->name), [
info(sprintf(__('Do you want to delete shifttype %s?'), $shifttype['name']), true), info(sprintf(__('Do you want to delete shifttype %s?'), $shifttype->name), true),
form([ form([
buttons([ buttons([
button(page_link_to('shifttypes'), icon('x-lg') . __('cancel')), button(page_link_to('shifttypes'), icon('x-lg') . __('cancel')),
@ -37,7 +40,7 @@ function ShiftType_delete_view($shifttype)
/** /**
* @param string $name * @param string $name
* @param string $description * @param string $description
* @param int|bool $shifttype_id * @param int $shifttype_id
* @return string * @return string
*/ */
function ShiftType_edit_view($name, $description, $shifttype_id) function ShiftType_edit_view($name, $description, $shifttype_id)
@ -57,56 +60,56 @@ function ShiftType_edit_view($name, $description, $shifttype_id)
} }
/** /**
* @param array $shifttype * @param ShiftType $shifttype
* @return string * @return string
*/ */
function ShiftType_view($shifttype) function ShiftType_view(ShiftType $shifttype)
{ {
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$title = $shifttype['name']; $title = $shifttype->name;
return page_with_title($title, [ return page_with_title($title, [
msg(), msg(),
buttons([ buttons([
button(page_link_to('shifttypes'), shifttypes_title(), 'back'), button(page_link_to('shifttypes'), shifttypes_title(), 'back'),
button( button(
page_link_to('shifttypes', ['action' => 'edit', 'shifttype_id' => $shifttype['id']]), page_link_to('shifttypes', ['action' => 'edit', 'shifttype_id' => $shifttype->id]),
__('edit'), __('edit'),
'edit' 'edit'
), ),
button( button(
page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype['id']]), page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype->id]),
__('delete'), __('delete'),
'delete' 'delete'
) )
]), ]),
heading(__('Description'), 2), heading(__('Description'), 2),
$parsedown->parse((string)$shifttype['description']) $parsedown->parse($shifttype->description)
], true); ], true);
} }
/** /**
* @param array[] $shifttypes * @param ShiftType[]|array[]|Collection $shifttypes
* @return string * @return string
*/ */
function ShiftTypes_list_view($shifttypes) function ShiftTypes_list_view($shifttypes)
{ {
foreach ($shifttypes as &$shifttype) { foreach ($shifttypes as $shifttype) {
$shifttype['name'] = '<a href="' $shifttype->name = '<a href="'
. page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype['id']]) . page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id])
. '">' . '">'
. $shifttype['name'] . $shifttype->name
. '</a>'; . '</a>';
$shifttype['actions'] = table_buttons([ $shifttype->actions = table_buttons([
button( button(
page_link_to( page_link_to(
'shifttypes', 'shifttypes',
['action' => 'edit', 'shifttype_id' => $shifttype['id']] ['action' => 'edit', 'shifttype_id' => $shifttype->id]
), ),
__('edit'), __('edit'),
'btn-sm' 'btn-sm'
), ),
button( button(
page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype['id']]), page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype->id]),
__('delete'), __('delete'),
'btn-sm' 'btn-sm'
) )

View File

@ -1,6 +1,7 @@
<?php <?php
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@ -104,13 +105,13 @@ function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null)
/** /**
* @param array $shift * @param array $shift
* @param array $shifttype * @param ShiftType $shifttype
* @param Room $room * @param Room $room
* @param array[] $angeltypes_source * @param array[] $angeltypes_source
* @param ShiftSignupState $shift_signup_state * @param ShiftSignupState $shift_signup_state
* @return string * @return string
*/ */
function Shift_view($shift, $shifttype, Room $room, $angeltypes_source, ShiftSignupState $shift_signup_state) function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source, ShiftSignupState $shift_signup_state)
{ {
$shift_admin = auth()->can('admin_shifts'); $shift_admin = auth()->can('admin_shifts');
$user_shift_admin = auth()->can('user_shifts_admin'); $user_shift_admin = auth()->can('user_shifts_admin');
@ -166,7 +167,7 @@ function Shift_view($shift, $shifttype, Room $room, $angeltypes_source, ShiftSig
$buttons = [ $buttons = [
$shift_admin ? button(shift_edit_link($shift), icon('pencil') . __('edit')) : '', $shift_admin ? button(shift_edit_link($shift), icon('pencil') . __('edit')) : '',
$shift_admin ? button(shift_delete_link($shift), icon('trash') . __('delete')) : '', $shift_admin ? button(shift_delete_link($shift), icon('trash') . __('delete')) : '',
$admin_shifttypes ? button(shifttype_link($shifttype), $shifttype['name']) : '', $admin_shifttypes ? button(shifttype_link($shifttype), $shifttype->name) : '',
$admin_rooms ? button(room_link($room), icon('geo-alt') . $room->name) : '', $admin_rooms ? button(room_link($room), icon('geo-alt') . $room->name) : '',
]; ];
} }
@ -181,7 +182,7 @@ function Shift_view($shift, $shifttype, Room $room, $angeltypes_source, ShiftSig
]), ]),
div('col-sm-6', [ div('col-sm-6', [
'<h2>' . __('Description') . '</h2>', '<h2>' . __('Description') . '</h2>',
$parsedown->parse((string)$shifttype['description']), $parsedown->parse($shifttype->description),
$parsedown->parse((string)$shift['description']), $parsedown->parse((string)$shift['description']),
]) ])
]); ]);

View File

@ -6,6 +6,7 @@ use Carbon\Carbon;
use Engelsystem\Models\BaseModel; use Engelsystem\Models\BaseModel;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\Builder as QueryBuilder;
@ -20,6 +21,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property Carbon $updated_at * @property Carbon $updated_at
* *
* @property-read QueryBuilder|Collection|ScheduleShift[] $scheduleShifts * @property-read QueryBuilder|Collection|ScheduleShift[] $scheduleShifts
* @property-read QueryBuilder|ShiftType $shiftType
* *
* @method static QueryBuilder|Schedule[] whereId($value) * @method static QueryBuilder|Schedule[] whereId($value)
* @method static QueryBuilder|Schedule[] whereName($value) * @method static QueryBuilder|Schedule[] whereName($value)
@ -56,8 +58,16 @@ class Schedule extends BaseModel
/** /**
* @return HasMany * @return HasMany
*/ */
public function scheduleShifts() public function scheduleShifts(): HasMany
{ {
return $this->hasMany(ScheduleShift::class); return $this->hasMany(ScheduleShift::class);
} }
/**
* @return BelongsTo
*/
public function shiftType(): BelongsTo
{
return $this->belongsTo(ShiftType::class, 'shift_type', 'id');
}
} }

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Models\Shifts;
use Engelsystem\Models\BaseModel;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Query\Builder as QueryBuilder;
/**
* @property int $id
* @property string $name
* @property string $description
*
* @property-read Collection|Schedule[] $schedules
*
* @method static QueryBuilder|ShiftType[] whereId($value)
* @method static QueryBuilder|ShiftType[] whereName($value)
* @method static QueryBuilder|ShiftType[] whereDescription($value)
*/
class ShiftType extends BaseModel
{
use HasFactory;
/** @var array */
protected $fillable = [
'name',
'description',
];
/**
* @return HasMany
*/
public function schedules(): HasMany
{
return $this->hasMany(Schedule::class, 'shift_type');
}
}

View File

@ -4,22 +4,25 @@ namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Models\Shifts\Schedule; use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\ScheduleShift; use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Test\Unit\Models\ModelTest; use Engelsystem\Test\Unit\Models\ModelTest;
class ScheduleTest extends ModelTest class ScheduleTest extends ModelTest
{ {
protected array $data = [
'url' => 'https://foo.bar/schedule.xml',
'name' => 'Testing',
'shift_type' => 1,
'minutes_before' => 10,
'minutes_after' => 10,
];
/** /**
* @covers \Engelsystem\Models\Shifts\Schedule::scheduleShifts * @covers \Engelsystem\Models\Shifts\Schedule::scheduleShifts
*/ */
public function testScheduleShifts() public function testScheduleShifts(): void
{ {
$schedule = new Schedule([ $schedule = new Schedule($this->data);
'url' => 'https://foo.bar/schedule.xml',
'name' => 'Testing',
'shift_type' => 0,
'minutes_before' => 10,
'minutes_after' => 10,
]);
$schedule->save(); $schedule->save();
(new ScheduleShift(['shift_id' => 1, 'schedule_id' => $schedule->id, 'guid' => 'a']))->save(); (new ScheduleShift(['shift_id' => 1, 'schedule_id' => $schedule->id, 'guid' => 'a']))->save();
@ -28,4 +31,19 @@ class ScheduleTest extends ModelTest
$this->assertCount(3, $schedule->scheduleShifts); $this->assertCount(3, $schedule->scheduleShifts);
} }
/**
* @covers \Engelsystem\Models\Shifts\Schedule::shiftType
*/
public function testShiftType(): void
{
$st = new ShiftType(['name' => 'Shift Type', 'description' => '']);
$st->save();
$schedule = new Schedule($this->data);
$schedule->save();
$schedule->shiftType()->associate($st);
$this->assertEquals('Shift Type', Schedule::find(1)->shiftType->name);
}
} }

View File

@ -0,0 +1,24 @@
<?php
namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Test\Unit\Models\ModelTest;
class ShiftTypeTest extends ModelTest
{
/**
* @covers \Engelsystem\Models\Shifts\ShiftType::schedules
*/
public function testSchedules(): void
{
$shiftType = new ShiftType(['name' => 'Test type', 'description' => 'Foo bar baz']);
$shiftType->save();
Schedule::factory()->create();
Schedule::factory(2)->create(['shift_type' => 1]);
$this->assertCount(2, ShiftType::find(1)->schedules);
}
}