Rename rooms to locations

This commit is contained in:
Igor Scheller 2023-10-15 19:25:55 +02:00 committed by msquare
parent a31534d9b7
commit 7f6e1ff18e
56 changed files with 642 additions and 556 deletions

View File

@ -163,14 +163,14 @@ $route->addGroup(
} }
); );
// Rooms // Locations
$route->addGroup( $route->addGroup(
'/rooms', '/locations',
function (RouteCollector $route): void { function (RouteCollector $route): void {
$route->get('', 'Admin\\RoomsController@index'); $route->get('', 'Admin\\LocationsController@index');
$route->post('', 'Admin\\RoomsController@delete'); $route->post('', 'Admin\\LocationsController@delete');
$route->get('/edit[/{room_id:\d+}]', 'Admin\\RoomsController@edit'); $route->get('/edit[/{location_id:\d+}]', 'Admin\\LocationsController@edit');
$route->post('/edit[/{room_id:\d+}]', 'Admin\\RoomsController@save'); $route->post('/edit[/{location_id:\d+}]', 'Admin\\LocationsController@save');
} }
); );

View File

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models; namespace Database\Factories\Engelsystem\Models;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
class RoomFactory extends Factory class LocationFactory extends Factory
{ {
/** @var string */ /** @var string */
protected $model = Room::class; // phpcs:ignore protected $model = Location::class; // phpcs:ignore
public function definition(): array public function definition(): array
{ {

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts; namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
@ -17,11 +17,11 @@ class NeededAngelTypeFactory extends Factory
public function definition(): array public function definition(): array
{ {
$forRoom = $this->faker->boolean(); $forLocation = $this->faker->boolean();
return [ return [
'room_id' => $forRoom ? Room::factory() : null, 'location_id' => $forLocation ? Location::factory() : null,
'shift_id' => $forRoom ? null : Shift::factory(), 'shift_id' => $forLocation ? null : Shift::factory(),
'angel_type_id' => AngelType::factory(), 'angel_type_id' => AngelType::factory(),
'count' => $this->faker->numberBetween(1, 5), 'count' => $this->faker->numberBetween(1, 5),
]; ];

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Database\Factories\Engelsystem\Models\Shifts; namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType; use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
@ -25,7 +25,7 @@ class ShiftFactory extends Factory
'start' => $start, 'start' => $start,
'end' => $this->faker->dateTimeInInterval($start, '+3 hours'), 'end' => $this->faker->dateTimeInInterval($start, '+3 hours'),
'shift_type_id' => ShiftType::factory(), 'shift_type_id' => ShiftType::factory(),
'room_id' => Room::factory(), 'location_id' => Location::factory(),
'transaction_id' => $this->faker->optional()->uuid(), 'transaction_id' => $this->faker->optional()->uuid(),
'created_by' => User::factory(), 'created_by' => User::factory(),
'updated_by' => $this->faker->optional(.3)->boolean() ? User::factory() : null, 'updated_by' => $this->faker->optional(.3)->boolean() ? User::factory() : null,

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class RenameRoomsToLocations extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
$this->schema->rename('rooms', 'locations');
$this->schema->table('shifts', function (Blueprint $table): void {
$table->renameColumn('room_id', 'location_id');
});
$this->schema->table('needed_angel_types', function (Blueprint $table): void {
$table->renameColumn('room_id', 'location_id');
});
$db = $this->schema->getConnection();
$db->table('privileges')->where('name', 'admin_rooms')->update([
'name' => 'admin_locations',
'description' => 'Manage locations',
]);
$db->table('privileges')->where('name', 'view_rooms')->update([
'name' => 'view_locations',
'description' => 'User can view locations',
]);
$db->table('privileges')->where('name', 'schedule.import')->update([
'description' => 'Import locations and shifts from schedule.xml',
]);
}
/**
* Reverse the migration
*/
public function down(): void
{
$this->schema->rename('locations', 'rooms');
$this->schema->table('shifts', function (Blueprint $table): void {
$table->renameColumn('location_id', 'room_id');
});
$this->schema->table('needed_angel_types', function (Blueprint $table): void {
$table->renameColumn('location_id', 'room_id');
});
$db = $this->schema->getConnection();
$db->table('privileges')->where('name', 'admin_locations')->update([
'name' => 'admin_rooms',
'description' => 'Räume administrieren',
]);
$db->table('privileges')->where('name', 'view_locations')->update([
'name' => 'view_rooms',
'description' => 'User can view rooms',
]);
$db->table('privileges')->where('name', 'schedule.import')->update([
'description' => 'Import rooms and shifts from schedule.xml',
]);
}
}

View File

@ -2,7 +2,7 @@
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\UserAngelType; use Engelsystem\Models\UserAngelType;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftsFilterRenderer; use Engelsystem\ShiftsFilterRenderer;
@ -243,13 +243,13 @@ function angeltype_controller_shiftsFilterDays(AngelType $angeltype)
function angeltype_controller_shiftsFilter(AngelType $angeltype, $days) function angeltype_controller_shiftsFilter(AngelType $angeltype, $days)
{ {
$request = request(); $request = request();
$roomIds = Room::query() $locationIds = Location::query()
->select('id') ->select('id')
->pluck('id') ->pluck('id')
->toArray(); ->toArray();
$shiftsFilter = new ShiftsFilter( $shiftsFilter = new ShiftsFilter(
auth()->can('user_shifts_admin'), auth()->can('user_shifts_admin'),
$roomIds, $locationIds,
[$angeltype->id] [$angeltype->id]
); );
$selected_day = date('Y-m-d'); $selected_day = date('Y-m-d');

View File

@ -1,29 +1,29 @@
<?php <?php
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftsFilterRenderer; use Engelsystem\ShiftsFilterRenderer;
/** /**
* Room controllers for managing everything room related. * Location controllers for managing everything location related.
*/ */
/** /**
* View a room with its shifts. * View a location with its shifts.
* *
* @return array * @return array
*/ */
function room_controller(): array function location_controller(): array
{ {
if (!auth()->can('view_rooms')) { if (!auth()->can('view_locations')) {
throw_redirect(page_link_to()); throw_redirect(page_link_to());
} }
$request = request(); $request = request();
$room = load_room(); $location = load_location();
$all_shifts = $room->shifts->sortBy('start'); $all_shifts = $location->shifts->sortBy('start');
$days = []; $days = [];
foreach ($all_shifts as $shift) { foreach ($all_shifts as $shift) {
$day = $shift->start->format('Y-m-d'); $day = $shift->start->format('Y-m-d');
@ -34,7 +34,7 @@ function room_controller(): array
$shiftsFilter = new ShiftsFilter( $shiftsFilter = new ShiftsFilter(
true, true,
[$room->id], [$location->id],
AngelType::query()->get('id')->pluck('id')->toArray() AngelType::query()->get('id')->pluck('id')->toArray()
); );
$selected_day = date('Y-m-d'); $selected_day = date('Y-m-d');
@ -53,17 +53,17 @@ function room_controller(): array
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter); $shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
return [ return [
$room->name, $location->name,
Room_view($room, $shiftsFilterRenderer, $shiftCalendarRenderer), location_view($location, $shiftsFilterRenderer, $shiftCalendarRenderer),
]; ];
} }
/** /**
* Dispatch different room actions. * Dispatch different location actions.
* *
* @return array * @return array
*/ */
function rooms_controller(): array function locations_controller(): array
{ {
$request = request(); $request = request();
$action = $request->input('action'); $action = $request->input('action');
@ -72,36 +72,36 @@ function rooms_controller(): array
} }
return match ($action) { return match ($action) {
'view' => room_controller(), 'view' => location_controller(),
'list' => throw_redirect(page_link_to('admin/rooms')), 'list' => throw_redirect(page_link_to('admin/locations')),
default => throw_redirect(page_link_to('admin/rooms')), default => throw_redirect(page_link_to('admin/locations')),
}; };
} }
/** /**
* @param Room $room * @param Location $location
* @return string * @return string
*/ */
function room_link(Room $room) function location_link(Location $location)
{ {
return page_link_to('rooms', ['action' => 'view', 'room_id' => $room->id]); return page_link_to('locations', ['action' => 'view', 'location_id' => $location->id]);
} }
/** /**
* Loads room by request param room_id * Loads location by request param location_id
* *
* @return Room * @return Location
*/ */
function load_room() function load_location()
{ {
if (!test_request_int('room_id')) { if (!test_request_int('location_id')) {
throw_redirect(page_link_to()); throw_redirect(page_link_to());
} }
$room = Room::find(request()->input('room_id')); $location = Location::find(request()->input('location_id'));
if (!$room) { if (!$location) {
throw_redirect(page_link_to()); throw_redirect(page_link_to());
} }
return $room; return $location;
} }

View File

@ -1,8 +1,8 @@
<?php <?php
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Location;
use Engelsystem\Models\News; use Engelsystem\Models\News;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
@ -15,22 +15,22 @@ function public_dashboard_controller()
{ {
$filter = null; $filter = null;
if (request()->get('filtered')) { if (request()->get('filtered')) {
$requestRooms = check_request_int_array('rooms'); $requestLocations = check_request_int_array('locations');
$requestAngelTypes = check_request_int_array('types'); $requestAngelTypes = check_request_int_array('types');
if (!$requestRooms && !$requestAngelTypes) { if (!$requestLocations && !$requestAngelTypes) {
$sessionFilter = collect(session()->get('shifts-filter', [])); $sessionFilter = collect(session()->get('shifts-filter', []));
$requestRooms = $sessionFilter->get('rooms', []); $requestLocations = $sessionFilter->get('locations', []);
$requestAngelTypes = $sessionFilter->get('types', []); $requestAngelTypes = $sessionFilter->get('types', []);
} }
$angelTypes = collect(unrestricted_angeltypes()); $angelTypes = collect(unrestricted_angeltypes());
$rooms = $requestRooms ?: Room::orderBy('name')->get()->pluck('id')->toArray(); $locations = $requestLocations ?: Location::orderBy('name')->get()->pluck('id')->toArray();
$angelTypes = $requestAngelTypes ?: $angelTypes->pluck('id')->toArray(); $angelTypes = $requestAngelTypes ?: $angelTypes->pluck('id')->toArray();
$filterValues = [ $filterValues = [
'userShiftsAdmin' => false, 'userShiftsAdmin' => false,
'filled' => [], 'filled' => [],
'rooms' => $rooms, 'locations' => $locations,
'types' => $angelTypes, 'types' => $angelTypes,
'startTime' => null, 'startTime' => null,
'endTime' => null, 'endTime' => null,
@ -87,7 +87,7 @@ function public_dashboard_controller_free_shift(Shift $shift, ShiftsFilter $filt
'duration' => round(($shift->end->timestamp - $shift->start->timestamp) / 3600), 'duration' => round(($shift->end->timestamp - $shift->start->timestamp) / 3600),
'shifttype_name' => $shift->shiftType->name, 'shifttype_name' => $shift->shiftType->name,
'title' => $shift->title, 'title' => $shift->title,
'room_name' => $shift->room->name, 'location_name' => $shift->location->name,
'needed_angels' => public_dashboard_needed_angels($shift->neededAngels, $filter), 'needed_angels' => public_dashboard_needed_angels($shift->neededAngels, $filter),
]; ];

View File

@ -120,10 +120,10 @@ function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype
} }
$angeltypes_select = $angeltypes->pluck('name', 'id')->toArray(); $angeltypes_select = $angeltypes->pluck('name', 'id')->toArray();
$room = $shift->room; $location = $shift->location;
return [ return [
ShiftEntry_create_title(), ShiftEntry_create_title(),
ShiftEntry_create_view_admin($shift, $room, $angeltype, $angeltypes_select, $signup_user, $users_select), ShiftEntry_create_view_admin($shift, $location, $angeltype, $angeltypes_select, $signup_user, $users_select),
]; ];
} }
@ -167,10 +167,10 @@ function shift_entry_create_controller_supporter(Shift $shift, AngelType $angelt
$users_select[$u->id] = $u->displayName; $users_select[$u->id] = $u->displayName;
} }
$room = $shift->room; $location = $shift->location;
return [ return [
ShiftEntry_create_title(), ShiftEntry_create_title(),
ShiftEntry_create_view_supporter($shift, $room, $angeltype, $signup_user, $users_select), ShiftEntry_create_view_supporter($shift, $location, $angeltype, $signup_user, $users_select),
]; ];
} }
@ -250,10 +250,10 @@ function shift_entry_create_controller_user(Shift $shift, AngelType $angeltype):
throw_redirect(shift_link($shift)); throw_redirect(shift_link($shift));
} }
$room = $shift->room; $location = $shift->location;
return [ return [
ShiftEntry_create_title(), ShiftEntry_create_title(),
ShiftEntry_create_view_user($shift, $room, $angeltype, $comment), ShiftEntry_create_view_user($shift, $location, $angeltype, $comment),
]; ];
} }

View File

@ -1,8 +1,8 @@
<?php <?php
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\ScheduleShift; use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType; use Engelsystem\Models\Shifts\ShiftType;
@ -67,9 +67,9 @@ function shift_edit_controller()
)); ));
} }
$rooms = []; $locations = [];
foreach (Room::orderBy('name')->get() as $room) { foreach (Location::orderBy('name')->get() as $location) {
$rooms[$room->id] = $room->name; $locations[$location->id] = $location->name;
} }
$angeltypes = AngelType::all()->pluck('name', 'id')->toArray(); $angeltypes = AngelType::all()->pluck('name', 'id')->toArray();
$shifttypes = ShiftType::all()->pluck('name', 'id')->toArray(); $shifttypes = ShiftType::all()->pluck('name', 'id')->toArray();
@ -84,7 +84,7 @@ function shift_edit_controller()
$shifttype_id = $shift->shift_type_id; $shifttype_id = $shift->shift_type_id;
$title = $shift->title; $title = $shift->title;
$description = $shift->description; $description = $shift->description;
$rid = $shift->room_id; $rid = $shift->location_id;
$start = $shift->start; $start = $shift->start;
$end = $shift->end; $end = $shift->end;
@ -97,7 +97,7 @@ function shift_edit_controller()
if ( if (
$request->has('rid') $request->has('rid')
&& preg_match('/^\d+$/', $request->input('rid')) && preg_match('/^\d+$/', $request->input('rid'))
&& isset($rooms[$request->input('rid')]) && isset($locations[$request->input('rid')])
) { ) {
$rid = $request->input('rid'); $rid = $request->input('rid');
} else { } else {
@ -154,7 +154,7 @@ function shift_edit_controller()
$shift->shift_type_id = $shifttype_id; $shift->shift_type_id = $shifttype_id;
$shift->title = $title; $shift->title = $title;
$shift->description = $description; $shift->description = $description;
$shift->room_id = $rid; $shift->location_id = $rid;
$shift->start = $start; $shift->start = $start;
$shift->end = $end; $shift->end = $end;
$shift->updatedBy()->associate(auth()->user()); $shift->updatedBy()->associate(auth()->user());
@ -210,7 +210,7 @@ function shift_edit_controller()
form([ form([
form_select('shifttype_id', __('Shifttype'), $shifttypes, $shifttype_id), form_select('shifttype_id', __('Shifttype'), $shifttypes, $shifttype_id),
form_text('title', __('title.title'), $title), form_text('title', __('title.title'), $title),
form_select('rid', __('Location:'), $rooms, $rid), form_select('rid', __('Location:'), $locations, $rid),
form_text('start', __('Start:'), $start->format('Y-m-d H:i')), form_text('start', __('Start:'), $start->format('Y-m-d H:i')),
form_text('end', __('End:'), $end->format('Y-m-d H:i')), form_text('end', __('End:'), $end->format('Y-m-d H:i')),
form_textarea('description', __('Additional description'), $description), form_textarea('description', __('Additional description'), $description),
@ -255,7 +255,7 @@ function shift_delete_controller()
'name' => $shift->shiftType->name, 'name' => $shift->shiftType->name,
'title' => $shift->title, 'title' => $shift->title,
'type' => $entry->angelType->name, 'type' => $entry->angelType->name,
'room' => $shift->room, 'location' => $shift->location,
'freeloaded' => $entry->freeloaded, 'freeloaded' => $entry->freeloaded,
]); ]);
} }
@ -312,7 +312,7 @@ function shift_controller()
} }
$shifttype = $shift->shiftType; $shifttype = $shift->shiftType;
$room = $shift->room; $location = $shift->location;
/** @var AngelType[] $angeltypes */ /** @var AngelType[] $angeltypes */
$angeltypes = AngelType::all(); $angeltypes = AngelType::all();
$user_shifts = Shifts_by_user($user->id); $user_shifts = Shifts_by_user($user->id);
@ -344,7 +344,7 @@ function shift_controller()
return [ return [
$shift->shiftType->name, $shift->shiftType->name,
Shift_view($shift, $shifttype, $room, $angeltypes, $shift_signup_state), Shift_view($shift, $shifttype, $location, $angeltypes, $shift_signup_state),
]; ];
} }

View File

@ -5,7 +5,7 @@ namespace Engelsystem\Events\Listener;
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Helpers\Shifts; use Engelsystem\Helpers\Shifts;
use Engelsystem\Mail\EngelsystemMailer; use Engelsystem\Mail\EngelsystemMailer;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\Models\Worklog; use Engelsystem\Models\Worklog;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -25,7 +25,7 @@ class Shift
string $name, string $name,
string $title, string $title,
string $type, string $type,
Room $room, Location $location,
bool $freeloaded bool $freeloaded
): void { ): void {
if ($freeloaded || $start > Carbon::now()) { if ($freeloaded || $start > Carbon::now()) {
@ -44,7 +44,7 @@ class Shift
$name, $name,
$title, $title,
$type, $type,
$room->name, $location->name,
$start->format(__('Y-m-d H:i')), $start->format(__('Y-m-d H:i')),
$end->format(__('Y-m-d H:i')) $end->format(__('Y-m-d H:i'))
); );
@ -63,7 +63,7 @@ class Shift
string $name, string $name,
string $title, string $title,
string $type, string $type,
Room $room, Location $location,
bool $freeloaded bool $freeloaded
): void { ): void {
if (!$user->settings->email_shiftinfo) { if (!$user->settings->email_shiftinfo) {
@ -79,7 +79,7 @@ class Shift
'title' => $title, 'title' => $title,
'start' => $start, 'start' => $start,
'end' => $end, 'end' => $end,
'room' => $room, 'location' => $location,
'freeloaded' => $freeloaded, 'freeloaded' => $freeloaded,
'username' => $user->displayName, 'username' => $user->displayName,
] ]

View File

@ -24,7 +24,7 @@ $includeFiles = [
__DIR__ . '/../includes/view/AngelTypes_view.php', __DIR__ . '/../includes/view/AngelTypes_view.php',
__DIR__ . '/../includes/view/EventConfig_view.php', __DIR__ . '/../includes/view/EventConfig_view.php',
__DIR__ . '/../includes/view/PublicDashboard_view.php', __DIR__ . '/../includes/view/PublicDashboard_view.php',
__DIR__ . '/../includes/view/Rooms_view.php', __DIR__ . '/../includes/view/Locations_view.php',
__DIR__ . '/../includes/view/ShiftCalendarLane.php', __DIR__ . '/../includes/view/ShiftCalendarLane.php',
__DIR__ . '/../includes/view/ShiftCalendarRenderer.php', __DIR__ . '/../includes/view/ShiftCalendarRenderer.php',
__DIR__ . '/../includes/view/ShiftCalendarShiftRenderer.php', __DIR__ . '/../includes/view/ShiftCalendarShiftRenderer.php',
@ -40,7 +40,7 @@ $includeFiles = [
__DIR__ . '/../includes/controller/angeltypes_controller.php', __DIR__ . '/../includes/controller/angeltypes_controller.php',
__DIR__ . '/../includes/controller/event_config_controller.php', __DIR__ . '/../includes/controller/event_config_controller.php',
__DIR__ . '/../includes/controller/public_dashboard_controller.php', __DIR__ . '/../includes/controller/public_dashboard_controller.php',
__DIR__ . '/../includes/controller/rooms_controller.php', __DIR__ . '/../includes/controller/locations_controller.php',
__DIR__ . '/../includes/controller/shift_entries_controller.php', __DIR__ . '/../includes/controller/shift_entries_controller.php',
__DIR__ . '/../includes/controller/shifts_controller.php', __DIR__ . '/../includes/controller/shifts_controller.php',
__DIR__ . '/../includes/controller/shifttypes_controller.php', __DIR__ . '/../includes/controller/shifttypes_controller.php',

View File

@ -11,8 +11,8 @@ function mail_shift_change(Shift $old_shift, Shift $new_shift)
$shiftEntries = $old_shift->shiftEntries() $shiftEntries = $old_shift->shiftEntries()
->with(['user', 'user.settings']) ->with(['user', 'user.settings'])
->get(); ->get();
$old_room = $old_shift->room; $old_location = $old_shift->location;
$new_room = $new_shift->room; $new_location = $new_shift->location;
$noticeable_changes = false; $noticeable_changes = false;
@ -51,8 +51,8 @@ function mail_shift_change(Shift $old_shift, Shift $new_shift)
$noticeable_changes = true; $noticeable_changes = true;
} }
if ($old_shift->room_id != $new_shift->room_id) { if ($old_shift->location_id != $new_shift->location_id) {
$message .= sprintf(__('* Shift Location changed from %s to %s'), $old_room->name, $new_room->name) . "\n"; $message .= sprintf(__('* Shift Location changed from %s to %s'), $old_location->name, $new_location->name) . "\n";
$noticeable_changes = true; $noticeable_changes = true;
} }
@ -67,7 +67,7 @@ function mail_shift_change(Shift $old_shift, Shift $new_shift)
$message .= $new_shift->shiftType->name . "\n"; $message .= $new_shift->shiftType->name . "\n";
$message .= $new_shift->title . "\n"; $message .= $new_shift->title . "\n";
$message .= $new_shift->start->format(__('Y-m-d H:i')) . ' - ' . $new_shift->end->format(__('H:i')) . "\n"; $message .= $new_shift->start->format(__('Y-m-d H:i')) . ' - ' . $new_shift->end->format(__('H:i')) . "\n";
$message .= $new_room->name . "\n\n"; $message .= $new_location->name . "\n\n";
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $new_shift->id]) . "\n"; $message .= url('/shifts', ['action' => 'view', 'shift_id' => $new_shift->id]) . "\n";
foreach ($shiftEntries as $shiftEntry) { foreach ($shiftEntries as $shiftEntry) {
@ -89,13 +89,11 @@ function mail_shift_assign(User $user, Shift $shift)
return; return;
} }
$room = $shift->room;
$message = __('You have been assigned to a Shift:') . "\n"; $message = __('You have been assigned to a Shift:') . "\n";
$message .= $shift->shiftType->name . "\n"; $message .= $shift->shiftType->name . "\n";
$message .= $shift->title . "\n"; $message .= $shift->title . "\n";
$message .= $shift->start->format(__('Y-m-d H:i')) . ' - ' . $shift->end->format(__('H:i')) . "\n"; $message .= $shift->start->format(__('Y-m-d H:i')) . ' - ' . $shift->end->format(__('H:i')) . "\n";
$message .= $room->name . "\n\n"; $message .= $shift->location->name . "\n\n";
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $shift->id]) . "\n"; $message .= url('/shifts', ['action' => 'view', 'shift_id' => $shift->id]) . "\n";
engelsystem_email_to_user($user, __('Assigned to Shift'), $message, true); engelsystem_email_to_user($user, __('Assigned to Shift'), $message, true);
@ -107,13 +105,11 @@ function mail_shift_removed(User $user, Shift $shift)
return; return;
} }
$room = $shift->room;
$message = __('You have been removed from a Shift:') . "\n"; $message = __('You have been removed from a Shift:') . "\n";
$message .= $shift->shiftType->name . "\n"; $message .= $shift->shiftType->name . "\n";
$message .= $shift->title . "\n"; $message .= $shift->title . "\n";
$message .= $shift->start->format(__('Y-m-d H:i')) . ' - ' . $shift->end->format(__('H:i')) . "\n"; $message .= $shift->start->format(__('Y-m-d H:i')) . ' - ' . $shift->end->format(__('H:i')) . "\n";
$message .= $room->name . "\n"; $message .= $shift->location->name . "\n";
engelsystem_email_to_user($user, __('Removed from Shift'), $message, true); engelsystem_email_to_user($user, __('Removed from Shift'), $message, true);
} }

View File

@ -23,19 +23,19 @@ function NeededAngelTypes_by_shift($shiftId)
FROM `needed_angel_types` FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id`
WHERE `shift_id` = ? WHERE `shift_id` = ?
ORDER BY `room_id` DESC', ORDER BY `location_id` DESC',
[$shiftId] [$shiftId]
); );
// Use settings from room // Use settings from location
if (count($needed_angeltypes_source) == 0) { if (count($needed_angeltypes_source) == 0) {
$needed_angeltypes_source = Db::select(' $needed_angeltypes_source = Db::select('
SELECT `needed_angel_types`.*, `angel_types`.`name`, `angel_types`.`restricted` SELECT `needed_angel_types`.*, `angel_types`.`name`, `angel_types`.`restricted`
FROM `needed_angel_types` FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id`
JOIN `shifts` ON `shifts`.`room_id` = `needed_angel_types`.`room_id` JOIN `shifts` ON `shifts`.`location_id` = `needed_angel_types`.`location_id`
WHERE `shifts`.`id` = ? WHERE `shifts`.`id` = ?
ORDER BY `room_id` DESC ORDER BY `location_id` DESC
', [$shiftId]); ', [$shiftId]);
} }

View File

@ -15,7 +15,7 @@ function ShiftEntry_onCreate(ShiftEntry $shiftEntry): void
'User ' . User_Nick_render($shiftEntry->user, true) 'User ' . User_Nick_render($shiftEntry->user, true)
. ' signed up for shift ' . $shiftEntry->shift->title . ' signed up for shift ' . $shiftEntry->shift->title
. ' (' . $shift->shiftType->name . ')' . ' (' . $shift->shiftType->name . ')'
. ' at ' . $shift->room->name . ' at ' . $shift->location->name
. ' from ' . $shift->start->format('Y-m-d H:i') . ' from ' . $shift->start->format('Y-m-d H:i')
. ' to ' . $shift->end->format('Y-m-d H:i') . ' to ' . $shift->end->format('Y-m-d H:i')
. ' as ' . $shiftEntry->angelType->name . ' as ' . $shiftEntry->angelType->name
@ -33,14 +33,14 @@ function ShiftEntry_onDelete(ShiftEntry $shiftEntry)
$signout_user = $shiftEntry->user; $signout_user = $shiftEntry->user;
$shift = Shift($shiftEntry->shift); $shift = Shift($shiftEntry->shift);
$shifttype = $shift->shiftType; $shifttype = $shift->shiftType;
$room = $shift->room; $location = $shift->location;
$angeltype = $shiftEntry->angelType; $angeltype = $shiftEntry->angelType;
engelsystem_log( engelsystem_log(
'Shift signout: ' . User_Nick_render($signout_user, true) 'Shift signout: ' . User_Nick_render($signout_user, true)
. ' from shift ' . $shift->title . ' from shift ' . $shift->title
. ' (' . $shifttype->name . ')' . ' (' . $shifttype->name . ')'
. ' at ' . $room->name . ' at ' . $location->name
. ' from ' . $shift->start->format('Y-m-d H:i') . ' from ' . $shift->start->format('Y-m-d H:i')
. ' to ' . $shift->end->format('Y-m-d H:i') . ' to ' . $shift->end->format('Y-m-d H:i')
. ' as ' . $angeltype->name . ' as ' . $angeltype->name

View File

@ -44,10 +44,10 @@ class ShiftsFilter
* ShiftsFilter constructor. * ShiftsFilter constructor.
* *
* @param bool $user_shifts_admin * @param bool $user_shifts_admin
* @param int[] $rooms * @param int[] $locations
* @param int[] $angelTypes * @param int[] $angelTypes
*/ */
public function __construct($user_shifts_admin = false, private $rooms = [], $angelTypes = []) public function __construct($user_shifts_admin = false, private $locations = [], $angelTypes = [])
{ {
$this->types = $angelTypes; $this->types = $angelTypes;
@ -68,7 +68,7 @@ class ShiftsFilter
return [ return [
'userShiftsAdmin' => $this->userShiftsAdmin, 'userShiftsAdmin' => $this->userShiftsAdmin,
'filled' => $this->filled, 'filled' => $this->filled,
'rooms' => $this->rooms, 'locations' => $this->locations,
'types' => $this->types, 'types' => $this->types,
'startTime' => $this->startTime, 'startTime' => $this->startTime,
'endTime' => $this->endTime, 'endTime' => $this->endTime,
@ -80,12 +80,12 @@ class ShiftsFilter
*/ */
public function sessionImport($data) public function sessionImport($data)
{ {
$this->userShiftsAdmin = $data['userShiftsAdmin']; $this->userShiftsAdmin = $data['userShiftsAdmin'] ?? false;
$this->filled = $data['filled']; $this->filled = $data['filled'] ?? [];
$this->rooms = $data['rooms']; $this->locations = $data['locations'] ?? [];
$this->types = $data['types']; $this->types = $data['types'] ?? [];
$this->startTime = $data['startTime']; $this->startTime = $data['startTime'] ?? null;
$this->endTime = $data['endTime']; $this->endTime = $data['endTime'] ?? null;
} }
/** /**
@ -163,20 +163,20 @@ class ShiftsFilter
/** /**
* @return int[] * @return int[]
*/ */
public function getRooms() public function getLocations()
{ {
if (count($this->rooms) == 0) { if (count($this->locations) == 0) {
return [0]; return [0];
} }
return $this->rooms; return $this->locations;
} }
/** /**
* @param int[] $rooms * @param int[] $locations
*/ */
public function setRooms($rooms) public function setLocations($locations)
{ {
$this->rooms = $rooms; $this->locations = $locations;
} }
/** /**

View File

@ -29,7 +29,7 @@ function Shifts_by_angeltype(AngelType $angeltype)
UNION UNION
SELECT DISTINCT `shifts`.* FROM `shifts` SELECT DISTINCT `shifts`.* FROM `shifts`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id` = `shifts`.`room_id` JOIN `needed_angel_types` ON `needed_angel_types`.`location_id` = `shifts`.`location_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `needed_angel_types`.`angel_type_id` = ? WHERE `needed_angel_types`.`angel_type_id` = ?
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
@ -60,7 +60,7 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
> (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND shift_entries.`freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') > (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND shift_entries.`freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND s.shift_id IS NULL AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
UNION UNION
@ -68,10 +68,10 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
FROM `shifts` FROM `shifts`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE (`end` > ? AND `start` < ?) WHERE (`end` > ? AND `start` < ?)
AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`location_id`=`shifts`.`location_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
> (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND `freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') > (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND `freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
) AS `tmp` ) AS `tmp`
ORDER BY `tmp`.`start` ORDER BY `tmp`.`start`
', [ ', [
@ -97,32 +97,32 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{ {
$sql = ' $sql = '
SELECT * FROM ( SELECT * FROM (
SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name` SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `locations`.`name` AS `location_name`
FROM `shifts` FROM `shifts`
JOIN `rooms` ON `shifts`.`room_id` = `rooms`.`id` JOIN `locations` ON `shifts`.`location_id` = `locations`.`id`
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id` JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id` = `shifts`.`id` JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id` = `shifts`.`id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `shifts`.`location_id` IN (' . implode(',', $shiftsFilter->getLocations()) . ')
AND `start` BETWEEN ? AND ? AND `start` BETWEEN ? AND ?
AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ') AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND s.shift_id IS NULL AND s.shift_id IS NULL
UNION UNION
SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name` SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `locations`.`name` AS `location_name`
FROM `shifts` FROM `shifts`
JOIN `rooms` ON `shifts`.`room_id` = `rooms`.`id` JOIN `locations` ON `shifts`.`location_id` = `locations`.`id`
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id` JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id`=`shifts`.`room_id` JOIN `needed_angel_types` ON `needed_angel_types`.`location_id`=`shifts`.`location_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `shifts`.`location_id` IN (' . implode(',', $shiftsFilter->getLocations()) . ')
AND `start` BETWEEN ? AND ? AND `start` BETWEEN ? AND ?
AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ') AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
) AS tmp_shifts ) AS tmp_shifts
ORDER BY `room_name`, `start` ORDER BY `location_name`, `start`
'; ';
$shiftsData = Db::select( $shiftsData = Db::select(
@ -161,7 +161,7 @@ function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id`=`shifts`.`id` JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id`=`shifts`.`id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `shifts`.`location_id` IN (' . implode(',', $shiftsFilter->getLocations()) . ')
AND shifts.`start` BETWEEN ? AND ? AND shifts.`start` BETWEEN ? AND ?
AND s.shift_id IS NULL AND s.shift_id IS NULL
@ -175,10 +175,10 @@ function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
`angel_types`.`restricted`, `angel_types`.`restricted`,
`angel_types`.`shift_self_signup` `angel_types`.`shift_self_signup`
FROM `shifts` FROM `shifts`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id`=`shifts`.`room_id` JOIN `needed_angel_types` ON `needed_angel_types`.`location_id`=`shifts`.`location_id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ') WHERE `shifts`.`location_id` IN (' . implode(',', $shiftsFilter->getLocations()) . ')
AND shifts.`start` BETWEEN ? AND ? AND shifts.`start` BETWEEN ? AND ?
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
'; ';
@ -228,7 +228,7 @@ function NeededAngeltype_by_Shift_and_Angeltype(Shift $shift, AngelType $angelty
`angel_types`.`restricted`, `angel_types`.`restricted`,
`angel_types`.`shift_self_signup` `angel_types`.`shift_self_signup`
FROM `shifts` FROM `shifts`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id`=`shifts`.`room_id` JOIN `needed_angel_types` ON `needed_angel_types`.`location_id`=`shifts`.`location_id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`id`=? WHERE `shifts`.`id`=?
@ -252,7 +252,7 @@ function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{ {
return ShiftEntry::with('user') return ShiftEntry::with('user')
->join('shifts', 'shifts.id', 'shift_entries.shift_id') ->join('shifts', 'shifts.id', 'shift_entries.shift_id')
->whereIn('shifts.room_id', $shiftsFilter->getRooms()) ->whereIn('shifts.location_id', $shiftsFilter->getLocations())
->whereBetween('start', [$shiftsFilter->getStart(), $shiftsFilter->getEnd()]) ->whereBetween('start', [$shiftsFilter->getStart(), $shiftsFilter->getEnd()])
->get(); ->get();
} }
@ -510,8 +510,8 @@ function Shifts_by_user($userId, $include_freeloaded_comments = false)
$shiftsData = Db::select( $shiftsData = Db::select(
' '
SELECT SELECT
`rooms`.*, `locations`.*,
`rooms`.name AS Name, `locations`.name AS Name,
`shift_types`.`id` AS `shifttype_id`, `shift_types`.`id` AS `shifttype_id`,
`shift_types`.`name`, `shift_types`.`name`,
`shift_entries`.`id` as shift_entry_id, `shift_entries`.`id` as shift_entry_id,
@ -525,7 +525,7 @@ function Shifts_by_user($userId, $include_freeloaded_comments = false)
FROM `shift_entries` FROM `shift_entries`
JOIN `shifts` ON (`shift_entries`.`shift_id` = `shifts`.`id`) JOIN `shifts` ON (`shift_entries`.`shift_id` = `shifts`.`id`)
JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`) JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`)
JOIN `rooms` ON (`shifts`.`room_id` = `rooms`.`id`) JOIN `locations` ON (`shifts`.`location_id` = `locations`.`id`)
WHERE shift_entries.`user_id` = ? WHERE shift_entries.`user_id` = ?
ORDER BY `start` ORDER BY `start`
', ',

View File

@ -24,7 +24,7 @@ function stats_currently_working(ShiftsFilter $filter = null)
)) AS `count` )) AS `count`
FROM `shifts` FROM `shifts`
WHERE (`end` >= NOW() AND `start` <= NOW()) WHERE (`end` >= NOW() AND `start` <= NOW())
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '')
); );
return $result['count'] ?: '-'; return $result['count'] ?: '-';
@ -49,18 +49,18 @@ function stats_hours_to_work(ShiftsFilter $filter = null)
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`end` >= NOW() WHERE `shifts`.`end` >= NOW()
AND s.shift_id IS NULL AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
UNION ALL UNION ALL
SELECT SELECT
(SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`location_id`=`shifts`.`location_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
* TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count` * TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count`
FROM `shifts` FROM `shifts`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE shifts.`end` >= NOW() WHERE shifts.`end` >= NOW()
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
) AS `tmp` ) AS `tmp`
' '
); );
@ -103,7 +103,7 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE shifts.`end` > NOW() AND shifts.`start` < ? WHERE shifts.`end` > NOW() AND shifts.`start` < ?
AND s.shift_id IS NULL AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
UNION ALL UNION ALL
@ -114,7 +114,7 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
FROM `needed_angel_types` FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `needed_angel_types`.`room_id`=`shifts`.`room_id` AND `needed_angel_types`.`location_id`=`shifts`.`location_id`
' . ($filter ? 'AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ' . ($filter ? 'AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - ( ) - (
SELECT COUNT(*) SELECT COUNT(*)
@ -131,7 +131,7 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `end` > NOW() AND `start` < ? WHERE `end` > NOW() AND `start` < ?
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
) AS `tmp`', [ ) AS `tmp`', [
$in3hours, $in3hours,
$in3hours, $in3hours,
@ -185,7 +185,7 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE shifts.`end` > ? AND shifts.`start` < ? WHERE shifts.`end` > ? AND shifts.`start` < ?
AND s.shift_id IS NULL AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
UNION ALL UNION ALL
@ -196,7 +196,7 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
FROM `needed_angel_types` FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id` JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `needed_angel_types`.`room_id`=`shifts`.`room_id` AND `needed_angel_types`.`location_id`=`shifts`.`location_id`
' . ($filter ? 'AND angel_types.id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ' . ($filter ? 'AND angel_types.id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - ( ) - (
SELECT COUNT(*) FROM `shift_entries` SELECT COUNT(*) FROM `shift_entries`
@ -212,7 +212,7 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `end` > ? AND `start` < ? WHERE `end` > ? AND `start` < ?
AND NOT s.shift_id IS NULL AND NOT s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ' . ($filter ? 'AND shifts.location_id IN (' . implode(',', $filter->getLocations()) . ')' : '') . '
) AS `tmp`', [ ) AS `tmp`', [
$night_start, $night_start,
$night_end, $night_end,

View File

@ -4,7 +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\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Schedule; use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
@ -44,8 +44,8 @@ function admin_shifts()
$shift_over_midnight = true; $shift_over_midnight = true;
// Locations laden // Locations laden
$rooms = Room::orderBy('name')->get(); $locations = Location::orderBy('name')->get();
$room_array = $rooms->pluck('name', 'id')->toArray(); $location_array = $locations->pluck('name', 'id')->toArray();
// Load angeltypes // Load angeltypes
/** @var AngelType[] $types */ /** @var AngelType[] $types */
@ -85,14 +85,14 @@ function admin_shifts()
// Auswahl der sichtbaren Locations für die Schichten // Auswahl der sichtbaren Locations für die Schichten
if ( if (
$request->has('rid') $request->has('lid')
&& preg_match('/^\d+$/', $request->input('rid')) && preg_match('/^\d+$/', $request->input('lid'))
&& isset($room_array[$request->input('rid')]) && isset($location_array[$request->input('lid')])
) { ) {
$rid = $request->input('rid'); $lid = $request->input('lid');
} else { } else {
$valid = false; $valid = false;
$rid = $rooms->first()->id; $lid = $locations->first()->id;
error(__('Please select a location.')); error(__('Please select a location.'));
} }
@ -208,7 +208,7 @@ function admin_shifts()
// Alle Eingaben in Ordnung // Alle Eingaben in Ordnung
if ($valid) { if ($valid) {
if ($angelmode == 'location') { if ($angelmode == 'location') {
$needed_angel_types = NeededAngelType::whereRoomId($rid) $needed_angel_types = NeededAngelType::whereLocationId($lid)
->pluck('count', 'angel_type_id') ->pluck('count', 'angel_type_id')
->toArray() + $needed_angel_types; ->toArray() + $needed_angel_types;
} }
@ -218,7 +218,7 @@ function admin_shifts()
$shifts[] = [ $shifts[] = [
'start' => $start, 'start' => $start,
'end' => $end, 'end' => $end,
'room_id' => $rid, 'location_id' => $lid,
'title' => $title, 'title' => $title,
'shift_type_id' => $shifttype_id, 'shift_type_id' => $shifttype_id,
'description' => $description, 'description' => $description,
@ -238,7 +238,7 @@ function admin_shifts()
$shifts[] = [ $shifts[] = [
'start' => $shift_start, 'start' => $shift_start,
'end' => $shift_end, 'end' => $shift_end,
'room_id' => $rid, 'location_id' => $lid,
'title' => $title, 'title' => $title,
'shift_type_id' => $shifttype_id, 'shift_type_id' => $shifttype_id,
'description' => $description, 'description' => $description,
@ -299,7 +299,7 @@ function admin_shifts()
$shifts[] = [ $shifts[] = [
'start' => $interval_start, 'start' => $interval_start,
'end' => $interval_end, 'end' => $interval_end,
'room_id' => $rid, 'location_id' => $lid,
'title' => $title, 'title' => $title,
'shift_type_id' => $shifttype_id, 'shift_type_id' => $shifttype_id,
'description' => $description, 'description' => $description,
@ -330,7 +330,7 @@ function admin_shifts()
. '</span>' . '</span>'
. ', ' . round($end->copy()->diffInMinutes($start) / 60, 2) . 'h' . ', ' . round($end->copy()->diffInMinutes($start) / 60, 2) . 'h'
. '<br>' . '<br>'
. Room_name_render(Room::find($shift['room_id'])), . location_name_render(Location::find($shift['location_id'])),
'title' => 'title' =>
ShiftType_name_render(ShiftType::find($shifttype_id)) ShiftType_name_render(ShiftType::find($shifttype_id))
. ($shift['title'] ? '<br />' . $shift['title'] : ''), . ($shift['title'] ? '<br />' . $shift['title'] : ''),
@ -367,7 +367,7 @@ function admin_shifts()
form_hidden('shifttype_id', $shifttype_id), form_hidden('shifttype_id', $shifttype_id),
form_hidden('description', $description), form_hidden('description', $description),
form_hidden('title', $title), form_hidden('title', $title),
form_hidden('rid', $rid), form_hidden('lid', $lid),
form_hidden('start', $request->input('start')), form_hidden('start', $request->input('start')),
form_hidden('end', $request->input('end')), form_hidden('end', $request->input('end')),
form_hidden('mode', $mode), form_hidden('mode', $mode),
@ -434,9 +434,9 @@ function admin_shifts()
$session->remove('admin_shifts_types'); $session->remove('admin_shifts_types');
} }
$rid = null; $lid = null;
if ($request->has('rid')) { if ($request->has('lid')) {
$rid = $request->input('rid'); $lid = $request->input('lid');
} }
$angel_types = ''; $angel_types = '';
foreach ($types as $type) { foreach ($types as $type) {
@ -467,7 +467,7 @@ function admin_shifts()
div('col-md-6 col-xl-5', [ div('col-md-6 col-xl-5', [
form_select('shifttype_id', __('Shifttype'), $shifttypes, $shifttype_id), form_select('shifttype_id', __('Shifttype'), $shifttypes, $shifttype_id),
form_text('title', __('title.title'), $title), form_text('title', __('title.title'), $title),
form_select('rid', __('Location'), $room_array, $rid), form_select('lid', __('Location'), $location_array, $lid),
]), ]),
div('col-md-6 col-xl-7', [ div('col-md-6 col-xl-7', [
form_textarea('description', __('Additional description'), $description), form_textarea('description', __('Additional description'), $description),
@ -599,7 +599,7 @@ function admin_shifts_history(): string
'name' => $shift->shiftType->name, 'name' => $shift->shiftType->name,
'title' => $shift->title, 'title' => $shift->title,
'type' => $entry->angelType->name, 'type' => $entry->angelType->name,
'room' => $shift->room, 'location' => $shift->location,
'freeloaded' => $entry->freeloaded, 'freeloaded' => $entry->freeloaded,
]); ]);
} }

View File

@ -16,7 +16,7 @@ use Engelsystem\Helpers\Schedule\XmlParser;
use Engelsystem\Helpers\Uuid; use Engelsystem\Helpers\Uuid;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Engelsystem\Models\Room as RoomModel; use Engelsystem\Models\Location;
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\Shift; use Engelsystem\Models\Shifts\Shift;
@ -179,7 +179,7 @@ class ImportSchedule extends BaseController
[ [
'schedule_id' => $scheduleUrl->id, 'schedule_id' => $scheduleUrl->id,
'schedule' => $schedule, 'schedule' => $schedule,
'rooms' => [ 'locations' => [
'add' => $newRooms, 'add' => $newRooms,
], ],
'shifts' => [ 'shifts' => [
@ -218,15 +218,15 @@ class ImportSchedule extends BaseController
$this->log('Started schedule "{name}" import', ['name' => $scheduleUrl->name]); $this->log('Started schedule "{name}" import', ['name' => $scheduleUrl->name]);
foreach ($newRooms as $room) { foreach ($newRooms as $room) {
$this->createRoom($room); $this->createLocation($room);
} }
$rooms = $this->getAllRooms(); $locations = $this->getAllLocations();
foreach ($newEvents as $event) { foreach ($newEvents as $event) {
$this->createEvent( $this->createEvent(
$event, $event,
$shiftType, $shiftType,
$rooms $locations
->where('name', $event->getRoom()->getName()) ->where('name', $event->getRoom()->getName())
->first(), ->first(),
$scheduleUrl $scheduleUrl
@ -237,7 +237,7 @@ class ImportSchedule extends BaseController
$this->updateEvent( $this->updateEvent(
$event, $event,
$shiftType, $shiftType,
$rooms $locations
->where('name', $event->getRoom()->getName()) ->where('name', $event->getRoom()->getName())
->first() ->first()
); );
@ -255,11 +255,11 @@ class ImportSchedule extends BaseController
return redirect($this->url, 303); return redirect($this->url, 303);
} }
protected function createRoom(Room $room): void protected function createLocation(Room $room): void
{ {
$roomModel = new RoomModel(); $location = new Location();
$roomModel->name = $room->getName(); $location->name = $room->getName();
$roomModel->save(); $location->save();
$this->log('Created schedule location "{location}"', ['location' => $room->getName()]); $this->log('Created schedule location "{location}"', ['location' => $room->getName()]);
} }
@ -269,12 +269,12 @@ class ImportSchedule extends BaseController
$shiftEntries = $this->db $shiftEntries = $this->db
->table('shift_entries') ->table('shift_entries')
->select([ ->select([
'shift_types.name', 'shifts.title', 'angel_types.name AS type', 'rooms.id AS room_id', 'shift_types.name', 'shifts.title', 'angel_types.name AS type', 'locations.id AS location_id',
'shifts.start', 'shifts.end', 'shift_entries.user_id', 'shift_entries.freeloaded', 'shifts.start', 'shifts.end', 'shift_entries.user_id', 'shift_entries.freeloaded',
]) ])
->join('shifts', 'shifts.id', 'shift_entries.shift_id') ->join('shifts', 'shifts.id', 'shift_entries.shift_id')
->join('schedule_shift', 'shifts.id', 'schedule_shift.shift_id') ->join('schedule_shift', 'shifts.id', 'schedule_shift.shift_id')
->join('rooms', 'rooms.id', 'shifts.room_id') ->join('locations', 'locations.id', 'shifts.location_id')
->join('angel_types', 'angel_types.id', 'shift_entries.angel_type_id') ->join('angel_types', 'angel_types.id', 'shift_entries.angel_type_id')
->join('shift_types', 'shift_types.id', 'shifts.shift_type_id') ->join('shift_types', 'shift_types.id', 'shifts.shift_type_id')
->where('schedule_shift.guid', $event->getGuid()) ->where('schedule_shift.guid', $event->getGuid())
@ -288,13 +288,13 @@ class ImportSchedule extends BaseController
'name' => $shiftEntry->name, 'name' => $shiftEntry->name,
'title' => $shiftEntry->title, 'title' => $shiftEntry->title,
'type' => $shiftEntry->type, 'type' => $shiftEntry->type,
'room' => RoomModel::find($shiftEntry->room_id), 'location' => Location::find($shiftEntry->location_id),
'freeloaded' => $shiftEntry->freeloaded, 'freeloaded' => $shiftEntry->freeloaded,
]); ]);
} }
} }
protected function createEvent(Event $event, int $shiftTypeId, RoomModel $room, ScheduleUrl $scheduleUrl): void protected function createEvent(Event $event, int $shiftTypeId, Location $location, ScheduleUrl $scheduleUrl): void
{ {
$user = auth()->user(); $user = auth()->user();
$eventTimeZone = Carbon::now()->timezone; $eventTimeZone = Carbon::now()->timezone;
@ -304,7 +304,7 @@ class ImportSchedule extends BaseController
$shift->shift_type_id = $shiftTypeId; $shift->shift_type_id = $shiftTypeId;
$shift->start = $event->getDate()->copy()->timezone($eventTimeZone); $shift->start = $event->getDate()->copy()->timezone($eventTimeZone);
$shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone); $shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone);
$shift->room()->associate($room); $shift->location()->associate($location);
$shift->url = $event->getUrl() ?? ''; $shift->url = $event->getUrl() ?? '';
$shift->transaction_id = Uuid::uuidBy($scheduleUrl->id, '5c4ed01e'); $shift->transaction_id = Uuid::uuidBy($scheduleUrl->id, '5c4ed01e');
$shift->createdBy()->associate($user); $shift->createdBy()->associate($user);
@ -319,7 +319,7 @@ class ImportSchedule extends BaseController
'Created schedule shift "{shift}" in "{location}" ({from} {to}, {guid})', 'Created schedule shift "{shift}" in "{location}" ({from} {to}, {guid})',
[ [
'shift' => $shift->title, 'shift' => $shift->title,
'location' => $shift->room->name, 'location' => $shift->location->name,
'from' => $shift->start->format(DateTimeInterface::RFC3339), 'from' => $shift->start->format(DateTimeInterface::RFC3339),
'to' => $shift->end->format(DateTimeInterface::RFC3339), 'to' => $shift->end->format(DateTimeInterface::RFC3339),
'guid' => $scheduleShift->guid, 'guid' => $scheduleShift->guid,
@ -327,7 +327,7 @@ class ImportSchedule extends BaseController
); );
} }
protected function updateEvent(Event $event, int $shiftTypeId, RoomModel $room): void protected function updateEvent(Event $event, int $shiftTypeId, Location $location): void
{ {
$user = auth()->user(); $user = auth()->user();
$eventTimeZone = Carbon::now()->timezone; $eventTimeZone = Carbon::now()->timezone;
@ -339,7 +339,7 @@ class ImportSchedule extends BaseController
$shift->shift_type_id = $shiftTypeId; $shift->shift_type_id = $shiftTypeId;
$shift->start = $event->getDate()->copy()->timezone($eventTimeZone); $shift->start = $event->getDate()->copy()->timezone($eventTimeZone);
$shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone); $shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone);
$shift->room()->associate($room); $shift->location()->associate($location);
$shift->url = $event->getUrl() ?? ''; $shift->url = $event->getUrl() ?? '';
$shift->updatedBy()->associate($user); $shift->updatedBy()->associate($user);
$shift->save(); $shift->save();
@ -348,7 +348,7 @@ class ImportSchedule extends BaseController
'Updated schedule shift "{shift}" in "{location}" ({from} {to}, {guid})', 'Updated schedule shift "{shift}" in "{location}" ({from} {to}, {guid})',
[ [
'shift' => $shift->title, 'shift' => $shift->title,
'location' => $shift->room->name, 'location' => $shift->location->name,
'from' => $shift->start->format(DateTimeInterface::RFC3339), 'from' => $shift->start->format(DateTimeInterface::RFC3339),
'to' => $shift->end->format(DateTimeInterface::RFC3339), 'to' => $shift->end->format(DateTimeInterface::RFC3339),
'guid' => $scheduleShift->guid, 'guid' => $scheduleShift->guid,
@ -367,7 +367,7 @@ class ImportSchedule extends BaseController
'Deleted schedule shift "{shift}" in {location} ({from} {to}, {guid})', 'Deleted schedule shift "{shift}" in {location} ({from} {to}, {guid})',
[ [
'shift' => $shift->title, 'shift' => $shift->title,
'location' => $shift->room->name, 'location' => $shift->location->name,
'from' => $shift->start->format(DateTimeInterface::RFC3339), 'from' => $shift->start->format(DateTimeInterface::RFC3339),
'to' => $shift->end->format(DateTimeInterface::RFC3339), 'to' => $shift->end->format(DateTimeInterface::RFC3339),
'guid' => $scheduleShift->guid, 'guid' => $scheduleShift->guid,
@ -377,7 +377,7 @@ class ImportSchedule extends BaseController
/** /**
* @param Request $request * @param Request $request
* @return Event[]|Room[]|RoomModel[] * @return Event[]|Room[]|Location[]
* @throws ErrorException * @throws ErrorException
*/ */
protected function getScheduleData(Request $request) protected function getScheduleData(Request $request)
@ -420,10 +420,10 @@ class ImportSchedule extends BaseController
protected function newRooms(array $scheduleRooms): array protected function newRooms(array $scheduleRooms): array
{ {
$newRooms = []; $newRooms = [];
$allRooms = $this->getAllRooms(); $allLocations = $this->getAllLocations();
foreach ($scheduleRooms as $room) { foreach ($scheduleRooms as $room) {
if ($allRooms->where('name', $room->getName())->count()) { if ($allLocations->where('name', $room->getName())->count()) {
continue; continue;
} }
@ -456,7 +456,7 @@ class ImportSchedule extends BaseController
$scheduleEvents = []; $scheduleEvents = [];
/** @var Event[] $deleteEvents */ /** @var Event[] $deleteEvents */
$deleteEvents = []; $deleteEvents = [];
$rooms = $this->getAllRooms(); $locations = $this->getAllLocations();
$eventTimeZone = Carbon::now()->timezone; $eventTimeZone = Carbon::now()->timezone;
foreach ($schedule->getDay() as $day) { foreach ($schedule->getDay() as $day) {
@ -480,16 +480,16 @@ class ImportSchedule extends BaseController
foreach ($existingShifts as $shift) { foreach ($existingShifts as $shift) {
$guid = $shift->guid; $guid = $shift->guid;
/** @var Shift $shift */ /** @var Shift $shift */
$shift = Shift::with('room')->find($shift->shift_id); $shift = Shift::with('location')->find($shift->shift_id);
$event = $scheduleEvents[$guid]; $event = $scheduleEvents[$guid];
$room = $rooms->where('name', $event->getRoom()->getName())->first(); $location = $locations->where('name', $event->getRoom()->getName())->first();
if ( if (
$shift->title != $event->getTitle() $shift->title != $event->getTitle()
|| $shift->shift_type_id != $shiftType || $shift->shift_type_id != $shiftType
|| $shift->start != $event->getDate() || $shift->start != $event->getDate()
|| $shift->end != $event->getEndDate() || $shift->end != $event->getEndDate()
|| $shift->room_id != ($room->id ?? '') || $shift->location_id != ($location->id ?? '')
|| $shift->url != ($event->getUrl() ?? '') || $shift->url != ($event->getUrl() ?? '')
) { ) {
$changeEvents[$guid] = $event; $changeEvents[$guid] = $event;
@ -514,13 +514,13 @@ class ImportSchedule extends BaseController
protected function eventFromScheduleShift(ScheduleShift $scheduleShift): Event protected function eventFromScheduleShift(ScheduleShift $scheduleShift): Event
{ {
/** @var Shift $shift */ /** @var Shift $shift */
$shift = Shift::with('room')->find($scheduleShift->shift_id); $shift = Shift::with('location')->find($scheduleShift->shift_id);
$duration = $shift->start->diff($shift->end); $duration = $shift->start->diff($shift->end);
return new Event( return new Event(
$scheduleShift->guid, $scheduleShift->guid,
0, 0,
new Room($shift->room->name), new Room($shift->location->name),
$shift->title, $shift->title,
'', '',
'n/a', 'n/a',
@ -534,11 +534,11 @@ class ImportSchedule extends BaseController
} }
/** /**
* @return RoomModel[]|Collection * @return Location[]|Collection
*/ */
protected function getAllRooms(): Collection protected function getAllLocations(): Collection
{ {
return RoomModel::all(); return Location::all();
} }
/** /**

View File

@ -51,7 +51,7 @@ function user_myshifts()
/** @var ShiftEntry $shiftEntry */ /** @var ShiftEntry $shiftEntry */
$shiftEntry = ShiftEntry::where('id', $shift_entry_id) $shiftEntry = ShiftEntry::where('id', $shift_entry_id)
->where('user_id', $shifts_user->id) ->where('user_id', $shifts_user->id)
->with(['shift', 'shift.shiftType', 'shift.room', 'user']) ->with(['shift', 'shift.shiftType', 'shift.location', 'user'])
->first(); ->first();
if (!empty($shiftEntry)) { if (!empty($shiftEntry)) {
$shift = $shiftEntry->shift; $shift = $shiftEntry->shift;
@ -97,7 +97,7 @@ function user_myshifts()
return ShiftEntry_edit_view( return ShiftEntry_edit_view(
$shifts_user, $shifts_user,
$shift->start->format(__('Y-m-d H:i')) . ', ' . shift_length($shift), $shift->start->format(__('Y-m-d H:i')) . ', ' . shift_length($shift),
$shift->room->name, $shift->location->name,
$shift->shiftType->name, $shift->shiftType->name,
$shiftEntry->angelType->name, $shiftEntry->angelType->name,
$shiftEntry->user_comment, $shiftEntry->user_comment,

View File

@ -3,7 +3,7 @@
use Engelsystem\Database\Db; use Engelsystem\Database\Db;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\UserAngelType; use Engelsystem\Models\UserAngelType;
@ -107,40 +107,40 @@ function update_ShiftsFilter(ShiftsFilter $shiftsFilter, $user_shifts_admin, $da
{ {
$shiftsFilter->setUserShiftsAdmin($user_shifts_admin); $shiftsFilter->setUserShiftsAdmin($user_shifts_admin);
$shiftsFilter->setFilled(check_request_int_array('filled', $shiftsFilter->getFilled())); $shiftsFilter->setFilled(check_request_int_array('filled', $shiftsFilter->getFilled()));
$shiftsFilter->setRooms(check_request_int_array('rooms', $shiftsFilter->getRooms())); $shiftsFilter->setLocations(check_request_int_array('locations', $shiftsFilter->getLocations()));
$shiftsFilter->setTypes(check_request_int_array('types', $shiftsFilter->getTypes())); $shiftsFilter->setTypes(check_request_int_array('types', $shiftsFilter->getTypes()));
update_ShiftsFilter_timerange($shiftsFilter, $days); update_ShiftsFilter_timerange($shiftsFilter, $days);
} }
/** /**
* @return Room[]|Collection * @return Location[]|Collection
*/ */
function load_rooms(bool $onlyWithActiveShifts = false) function load_locations(bool $onlyWithActiveShifts = false)
{ {
$rooms = Room::orderBy('name'); $locations = Location::orderBy('name');
if ($onlyWithActiveShifts) { if ($onlyWithActiveShifts) {
$roomIdsFromAngelType = NeededAngelType::query() $locationIdsFromAngelType = NeededAngelType::query()
->whereNotNull('room_id') ->whereNotNull('location_id')
->select('room_id'); ->select('location_id');
$roomIdsFromShift = Shift::query() $locationIdsFromShift = Shift::query()
->leftJoin('needed_angel_types', 'shifts.id', 'needed_angel_types.shift_id') ->leftJoin('needed_angel_types', 'shifts.id', 'needed_angel_types.shift_id')
->whereNotNull('needed_angel_types.shift_id') ->whereNotNull('needed_angel_types.shift_id')
->select('shifts.room_id'); ->select('shifts.location_id');
$rooms->whereIn('id', $roomIdsFromAngelType) $locations->whereIn('id', $locationIdsFromAngelType)
->orWhereIn('id', $roomIdsFromShift); ->orWhereIn('id', $locationIdsFromShift);
} }
$rooms = $rooms->get(); $locations = $locations->get();
if ($rooms->isEmpty()) { if ($locations->isEmpty()) {
error(__('The administration has not configured any locations yet.')); error(__('The administration has not configured any locations yet.'));
throw_redirect(page_link_to('/')); throw_redirect(page_link_to('/'));
} }
return $rooms; return $locations;
} }
/** /**
@ -233,7 +233,7 @@ function view_user_shifts()
$session = session(); $session = session();
$days = load_days(); $days = load_days();
$rooms = load_rooms(true); $locations = load_locations(true);
$types = load_types(); $types = load_types();
$ownAngelTypes = []; $ownAngelTypes = [];
@ -250,8 +250,8 @@ function view_user_shifts()
} }
if (!$session->has('shifts-filter')) { if (!$session->has('shifts-filter')) {
$room_ids = $rooms->pluck('id')->toArray(); $location_ids = $locations->pluck('id')->toArray();
$shiftsFilter = new ShiftsFilter(auth()->can('user_shifts_admin'), $room_ids, $ownAngelTypes); $shiftsFilter = new ShiftsFilter(auth()->can('user_shifts_admin'), $location_ids, $ownAngelTypes);
$session->set('shifts-filter', $shiftsFilter->sessionExport()); $session->set('shifts-filter', $shiftsFilter->sessionExport());
} }
@ -297,10 +297,10 @@ function view_user_shifts()
view(__DIR__ . '/../../resources/views/pages/user-shifts.html', [ view(__DIR__ . '/../../resources/views/pages/user-shifts.html', [
'title' => shifts_title(), 'title' => shifts_title(),
'add_link' => auth()->can('admin_shifts') ? $link : '', 'add_link' => auth()->can('admin_shifts') ? $link : '',
'room_select' => make_select( 'location_select' => make_select(
$rooms, $locations,
$shiftsFilter->getRooms(), $shiftsFilter->getLocations(),
'rooms', 'locations',
icon('pin-map-fill') . __('Locations') icon('pin-map-fill') . __('Locations')
), ),
'start_select' => html_select_key( 'start_select' => html_select_key(

View File

@ -1,7 +1,7 @@
<?php <?php
use Engelsystem\Models\Location;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room;
use Engelsystem\UserHintsRenderer; use Engelsystem\UserHintsRenderer;
/** /**
@ -79,7 +79,7 @@ function make_navigation()
$menu[] = toolbar_item_link(page_link_to($menu_page), '', $title, $menu_page == $page); $menu[] = toolbar_item_link(page_link_to($menu_page), '', $title, $menu_page == $page);
} }
$menu = make_room_navigation($menu); $menu = make_location_navigation($menu);
$admin_menu = []; $admin_menu = [];
$admin_pages = [ $admin_pages = [
@ -92,7 +92,7 @@ function make_navigation()
'admin/questions' => ['Answer questions', 'question.edit'], 'admin/questions' => ['Answer questions', 'question.edit'],
'shifttypes' => 'Shifttypes', 'shifttypes' => 'Shifttypes',
'admin_shifts' => 'Create shifts', 'admin_shifts' => 'Create shifts',
'admin/rooms' => ['room.rooms', 'admin_rooms'], 'admin/locations' => ['location.locations', 'admin_locations'],
'admin_groups' => 'Grouprights', 'admin_groups' => 'Grouprights',
'admin/schedule' => ['schedule.import', 'schedule.import'], 'admin/schedule' => ['schedule.import', 'schedule.import'],
'admin/logs' => ['log.log', 'admin_log'], 'admin/logs' => ['log.log', 'admin_log'],
@ -142,31 +142,36 @@ function menu_is_allowed(string $page, $options)
} }
/** /**
* Adds room navigation to the given menu. * Adds location navigation to the given menu.
* *
* @param string[] $menu Rendered menu * @param string[] $menu Rendered menu
* @return string[] * @return string[]
*/ */
function make_room_navigation($menu) function make_location_navigation($menu)
{ {
if (!auth()->can('view_rooms')) { if (!auth()->can('view_locations')) {
return $menu; return $menu;
} }
// Get a list of all rooms // Get a list of all locations
$rooms = Room::orderBy('name')->get(); $locations = Location::orderBy('name')->get();
$room_menu = []; $location_menu = [];
if (auth()->can('admin_rooms')) { if (auth()->can('admin_locations')) {
$room_menu[] = toolbar_dropdown_item(page_link_to('admin/rooms'), __('Manage locations'), false, 'list'); $location_menu[] = toolbar_dropdown_item(
page_link_to('admin/locations'),
__('Manage locations'),
false,
'list'
);
} }
if (count($room_menu) > 0) { if (count($location_menu) > 0) {
$room_menu[] = toolbar_dropdown_item_divider(); $location_menu[] = toolbar_dropdown_item_divider();
} }
foreach ($rooms as $room) { foreach ($locations as $location) {
$room_menu[] = toolbar_dropdown_item(room_link($room), $room->name, false, 'pin-map-fill'); $location_menu[] = toolbar_dropdown_item(location_link($location), $location->name, false, 'pin-map-fill');
} }
if (count($room_menu) > 0) { if (count($location_menu) > 0) {
$menu[] = toolbar_dropdown(__('Locations'), $room_menu); $menu[] = toolbar_dropdown(__('Locations'), $location_menu);
} }
return $menu; return $menu;
} }

View File

@ -1,17 +1,17 @@
<?php <?php
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\ShiftCalendarRenderer; use Engelsystem\ShiftCalendarRenderer;
use Engelsystem\ShiftsFilterRenderer; use Engelsystem\ShiftsFilterRenderer;
/** /**
* *
* @param Room $room * @param Location $location
* @param ShiftsFilterRenderer $shiftsFilterRenderer * @param ShiftsFilterRenderer $shiftsFilterRenderer
* @param ShiftCalendarRenderer $shiftCalendarRenderer * @param ShiftCalendarRenderer $shiftCalendarRenderer
* @return string * @return string
*/ */
function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, ShiftCalendarRenderer $shiftCalendarRenderer) function location_view(Location $location, ShiftsFilterRenderer $shiftsFilterRenderer, ShiftCalendarRenderer $shiftCalendarRenderer)
{ {
$user = auth()->user(); $user = auth()->user();
@ -21,33 +21,33 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
} }
$description = ''; $description = '';
if ($room->description) { if ($location->description) {
$description = '<h3>' . __('general.description') . '</h3>'; $description = '<h3>' . __('general.description') . '</h3>';
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$description .= $parsedown->parse($room->description); $description .= $parsedown->parse($location->description);
} }
$dect = ''; $dect = '';
if (config('enable_dect') && $room->dect) { if (config('enable_dect') && $location->dect) {
$dect = heading(__('Contact'), 3) $dect = heading(__('Contact'), 3)
. description([__('general.dect') => sprintf('<a href="tel:%s">%1$s</a>', $room->dect)]); . description([__('general.dect') => sprintf('<a href="tel:%s">%1$s</a>', $location->dect)]);
} }
$tabs = []; $tabs = [];
if ($room->map_url) { if ($location->map_url) {
$tabs[__('room.map_url')] = sprintf( $tabs[__('location.map_url')] = sprintf(
'<div class="map">' '<div class="map">'
. '<iframe style="width: 100%%; min-height: 400px; border: 0 none;" src="%s"></iframe>' . '<iframe style="width: 100%%; min-height: 400px; border: 0 none;" src="%s"></iframe>'
. '</div>', . '</div>',
$room->map_url $location->map_url
); );
} }
$tabs[__('Shifts')] = div('first', [ $tabs[__('Shifts')] = div('first', [
$shiftsFilterRenderer->render(page_link_to('rooms', [ $shiftsFilterRenderer->render(page_link_to('locations', [
'action' => 'view', 'action' => 'view',
'room_id' => $room->id, 'location_id' => $location->id,
]), ['rooms' => [$room->id]]), ]), ['locations' => [$location->id]]),
$shiftCalendarRenderer->render(), $shiftCalendarRenderer->render(),
]); ]);
@ -57,15 +57,15 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
$selected_tab = count($tabs) - 1; $selected_tab = count($tabs) - 1;
} }
$link = button(page_link_to('admin/rooms'), icon('chevron-left'), 'btn-sm'); $link = button(page_link_to('admin/locations'), icon('chevron-left'), 'btn-sm');
return page_with_title( return page_with_title(
(auth()->can('admin_rooms') ? $link . ' ' : '') . (auth()->can('admin_locations') ? $link . ' ' : '') .
icon('pin-map-fill') . $room->name, icon('pin-map-fill') . $location->name,
[ [
$assignNotice, $assignNotice,
auth()->can('admin_rooms') ? buttons([ auth()->can('admin_locations') ? buttons([
button( button(
page_link_to('admin/rooms/edit/' . $room->id), page_link_to('admin/locations/edit/' . $location->id),
icon('pencil') . __('edit') icon('pencil') . __('edit')
), ),
]) : '', ]) : '',
@ -79,14 +79,14 @@ function Room_view(Room $room, ShiftsFilterRenderer $shiftsFilterRenderer, Shift
/** /**
* *
* @param Room $room * @param Location $location
* @return string * @return string
*/ */
function Room_name_render(Room $room) function location_name_render(Location $location)
{ {
if (auth()->can('view_rooms')) { if (auth()->can('view_locations')) {
return '<a href="' . room_link($room) . '">' . icon('pin-map-fill') . $room->name . '</a>'; return '<a href="' . location_link($location) . '">' . icon('pin-map-fill') . $location->name . '</a>';
} }
return icon('pin-map-fill') . $room->name; return icon('pin-map-fill') . $location->name;
} }

View File

@ -58,7 +58,7 @@ function public_dashboard_view($stats, $free_shifts, $highlighted_news)
} }
$isFiltered = request()->get('filtered'); $isFiltered = request()->get('filtered');
$filter = collect(session()->get('shifts-filter'))->only(['rooms', 'types'])->toArray(); $filter = collect(session()->get('shifts-filter'))->only(['locations', 'types'])->toArray();
return page([ return page([
div('wrapper', [ div('wrapper', [
div('public-dashboard', [ div('public-dashboard', [
@ -98,7 +98,7 @@ function public_dashboard_shift_render($shift)
$panel_body .= ' (' . $shift['title'] . ')'; $panel_body .= ' (' . $shift['title'] . ')';
} }
$panel_body .= '<br>' . icon('pin-map-fill') . $shift['room_name']; $panel_body .= '<br>' . icon('pin-map-fill') . $shift['location_name'];
foreach ($shift['needed_angels'] as $needed_angels) { foreach ($shift['needed_angels'] as $needed_angels) {
$panel_body .= '<br>' . icon('person') $panel_body .= '<br>' . icon('person')

View File

@ -62,28 +62,28 @@ class ShiftCalendarRenderer
} }
/** /**
* Assigns the shifts to different lanes per room if they collide * Assigns the shifts to different lanes per location if they collide
* *
* @param Shift[] $shifts The shifts to assign * @param Shift[] $shifts The shifts to assign
* @return array Returns an array that assigns a room_id to an array of ShiftCalendarLane containing the shifts * @return array Returns an array that assigns a location_id to an array of ShiftCalendarLane containing the shifts
*/ */
private function assignShiftsToLanes($shifts) private function assignShiftsToLanes($shifts)
{ {
// array that assigns a room id to a list of lanes (per room) // array that assigns a location id to a list of lanes (per location)
$lanes = []; $lanes = [];
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$room = $shift->room; $location = $shift->location;
$header = Room_name_render($room); $header = location_name_render($location);
if (!isset($lanes[$room->id])) { if (!isset($lanes[$location->id])) {
// initialize room with one lane // initialize location with one lane
$lanes[$room->id] = [ $lanes[$location->id] = [
new ShiftCalendarLane($header), new ShiftCalendarLane($header),
]; ];
} }
// Try to add the shift to the existing lanes for this room // Try to add the shift to the existing lanes for this location
$shift_added = false; $shift_added = false;
foreach ($lanes[$room->id] as $lane) { foreach ($lanes[$location->id] as $lane) {
/** @var ShiftCalendarLane $lane */ /** @var ShiftCalendarLane $lane */
if ($lane->shiftFits($shift)) { if ($lane->shiftFits($shift)) {
$lane->addShift($shift); $lane->addShift($shift);
@ -91,11 +91,11 @@ class ShiftCalendarRenderer
break; break;
} }
} }
// If all lanes for this room are busy, create a new lane and add shift to it // If all lanes for this location are busy, create a new lane and add shift to it
if (!$shift_added) { if (!$shift_added) {
$newLane = new ShiftCalendarLane($header); $newLane = new ShiftCalendarLane($header);
$newLane->addShift($shift); $newLane->addShift($shift);
$lanes[$room->id][] = $newLane; $lanes[$location->id][] = $newLane;
} }
} }
@ -154,8 +154,8 @@ class ShiftCalendarRenderer
private function renderShiftLanes() private function renderShiftLanes()
{ {
$html = ''; $html = '';
foreach ($this->lanes as $room_lanes) { foreach ($this->lanes as $location_lanes) {
foreach ($room_lanes as $lane) { foreach ($location_lanes as $lane) {
$html .= $this->renderLane($lane); $html .= $this->renderLane($lane);
} }
} }

View File

@ -43,8 +43,6 @@ class ShiftCalendarShiftRenderer
$blocks = ceil(($shift->end->timestamp - $shift->start->timestamp) / ShiftCalendarRenderer::SECONDS_PER_ROW); $blocks = ceil(($shift->end->timestamp - $shift->start->timestamp) / ShiftCalendarRenderer::SECONDS_PER_ROW);
$blocks = max(1, $blocks); $blocks = max(1, $blocks);
$room = $shift->room;
return [ return [
$blocks, $blocks,
div( div(
@ -57,7 +55,7 @@ class ShiftCalendarShiftRenderer
$this->renderShiftHead($shift, $class, $shift_signup_state->getFreeEntries()), $this->renderShiftHead($shift, $class, $shift_signup_state->getFreeEntries()),
div('card-body ' . $this->classBg(), [ div('card-body ' . $this->classBg(), [
$info_text, $info_text,
Room_name_render($room), location_name_render($shift->location),
]), ]),
$shifts_row, $shifts_row,
] ]

View File

@ -1,7 +1,7 @@
<?php <?php
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
@ -75,7 +75,7 @@ function ShiftEntry_delete_title()
* Admin puts user into shift. * Admin puts user into shift.
* *
* @param Shift $shift * @param Shift $shift
* @param Room $room * @param Location $location
* @param AngelType $angeltype * @param AngelType $angeltype
* @param array $angeltypes_select * @param array $angeltypes_select
* @param User $signup_user * @param User $signup_user
@ -84,7 +84,7 @@ function ShiftEntry_delete_title()
*/ */
function ShiftEntry_create_view_admin( function ShiftEntry_create_view_admin(
Shift $shift, Shift $shift,
Room $room, Location $location,
AngelType $angeltype, AngelType $angeltype,
$angeltypes_select, $angeltypes_select,
$signup_user, $signup_user,
@ -95,7 +95,7 @@ function ShiftEntry_create_view_admin(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . $shift->shiftType->name
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $location),
info(__('Do you want to sign up the following user for this shift?'), true), info(__('Do you want to sign up the following user for this shift?'), true),
form([ form([
form_select('angeltype_id', __('Angeltype'), $angeltypes_select, $angeltype->id), form_select('angeltype_id', __('Angeltype'), $angeltypes_select, $angeltype->id),
@ -110,20 +110,25 @@ function ShiftEntry_create_view_admin(
* Supporter puts user into shift. * Supporter puts user into shift.
* *
* @param Shift $shift * @param Shift $shift
* @param Room $room * @param Location $location
* @param AngelType $angeltype * @param AngelType $angeltype
* @param User $signup_user * @param User $signup_user
* @param array $users_select * @param array $users_select
* @return string * @return string
*/ */
function ShiftEntry_create_view_supporter(Shift $shift, Room $room, AngelType $angeltype, $signup_user, $users_select) function ShiftEntry_create_view_supporter(
{ Shift $shift,
Location $location,
AngelType $angeltype,
$signup_user,
$users_select
) {
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . $shift->shiftType->name
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $location),
info(sprintf( info(sprintf(
__('Do you want to sign up the following user for this shift as %s?'), __('Do you want to sign up the following user for this shift as %s?'),
$angeltype->name $angeltype->name
@ -140,19 +145,19 @@ function ShiftEntry_create_view_supporter(Shift $shift, Room $room, AngelType $a
* User joining a shift. * User joining a shift.
* *
* @param Shift $shift * @param Shift $shift
* @param Room $room * @param Location $location
* @param AngelType $angeltype * @param AngelType $angeltype
* @param string $comment * @param string $comment
* @return string * @return string
*/ */
function ShiftEntry_create_view_user(Shift $shift, Room $room, AngelType $angeltype, $comment) function ShiftEntry_create_view_user(Shift $shift, Location $location, AngelType $angeltype, $comment)
{ {
$start = $shift->start->format(__('Y-m-d H:i')); $start = $shift->start->format(__('Y-m-d H:i'));
return page_with_title( return page_with_title(
ShiftEntry_create_title() . ': ' . $shift->shiftType->name ShiftEntry_create_title() . ': ' . $shift->shiftType->name
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>', . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
[ [
Shift_view_header($shift, $room), Shift_view_header($shift, $location),
info(sprintf(__('Do you want to sign up for this shift as %s?'), $angeltype->name), true), info(sprintf(__('Do you want to sign up for this shift as %s?'), $angeltype->name), true),
form([ form([
form_textarea('comment', __('Comment (for your eyes only):'), $comment), form_textarea('comment', __('Comment (for your eyes only):'), $comment),

View File

@ -1,7 +1,7 @@
<?php <?php
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\Shifts\ShiftType; use Engelsystem\Models\Shifts\ShiftType;
@ -14,10 +14,10 @@ use Illuminate\Support\Collection;
* Renders the basic shift view header. * Renders the basic shift view header.
* *
* @param Shift $shift * @param Shift $shift
* @param Room $room * @param Location $location
* @return string HTML * @return string HTML
*/ */
function Shift_view_header(Shift $shift, Room $room) function Shift_view_header(Shift $shift, Location $location)
{ {
return div('row', [ return div('row', [
div('col-sm-3 col-xs-6', [ div('col-sm-3 col-xs-6', [
@ -46,7 +46,7 @@ function Shift_view_header(Shift $shift, Room $room)
]), ]),
div('col-sm-3 col-xs-6', [ div('col-sm-3 col-xs-6', [
'<h4>' . __('Location') . '</h4>', '<h4>' . __('Location') . '</h4>',
'<p class="lead">' . Room_name_render($room) . '</p>', '<p class="lead">' . location_name_render($location) . '</p>',
]), ]),
]); ]);
} }
@ -109,16 +109,21 @@ function Shift_signup_button_render(Shift $shift, AngelType $angeltype)
/** /**
* @param Shift $shift * @param Shift $shift
* @param ShiftType $shifttype * @param ShiftType $shifttype
* @param Room $room * @param Location $location
* @param AngelType[]|Collection $angeltypes_source * @param AngelType[]|Collection $angeltypes_source
* @param ShiftSignupState $shift_signup_state * @param ShiftSignupState $shift_signup_state
* @return string * @return string
*/ */
function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_source, ShiftSignupState $shift_signup_state) function Shift_view(
{ Shift $shift,
ShiftType $shifttype,
Location $location,
$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');
$admin_rooms = auth()->can('admin_rooms'); $admin_locations = auth()->can('admin_locations');
$admin_shifttypes = auth()->can('shifttypes'); $admin_shifttypes = auth()->can('shifttypes');
$parsedown = new Parsedown(); $parsedown = new Parsedown();
@ -166,12 +171,12 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
} }
$buttons = []; $buttons = [];
if ($shift_admin || $admin_shifttypes || $admin_rooms) { if ($shift_admin || $admin_shifttypes || $admin_locations) {
$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('pin-map-fill') . $room->name) : '', $admin_locations ? button(location_link($location), icon('pin-map-fill') . $location->name) : '',
]; ];
} }
$buttons[] = button( $buttons[] = button(
@ -180,7 +185,7 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
); );
$content[] = buttons($buttons); $content[] = buttons($buttons);
$content[] = Shift_view_header($shift, $room); $content[] = Shift_view_header($shift, $location);
$content[] = div('row', [ $content[] = div('row', [
div('col-sm-6', [ div('col-sm-6', [
'<h2>' . __('Needed angels') . '</h2>', '<h2>' . __('Needed angels') . '</h2>',

View File

@ -313,7 +313,7 @@ function User_view_myshift(Shift $shift, $user_source, $its_me)
. ' - ' . ' - '
. $shift->end->format(__('H:i')), . $shift->end->format(__('H:i')),
'duration' => sprintf('%.2f', ($shift->end->timestamp - $shift->start->timestamp) / 3600) . '&nbsp;h', 'duration' => sprintf('%.2f', ($shift->end->timestamp - $shift->start->timestamp) / 3600) . '&nbsp;h',
'room' => Room_name_render($shift->room), 'location' => location_name_render($shift->location),
'shift_info' => $shift_info, 'shift_info' => $shift_info,
'comment' => '', 'comment' => '',
]; ];
@ -404,7 +404,7 @@ function User_view_myshifts(
$myshifts_table[] = [ $myshifts_table[] = [
'date' => '<b>' . __('Sum:') . '</b>', 'date' => '<b>' . __('Sum:') . '</b>',
'duration' => '<b>' . sprintf('%.2f', round($timeSum / 3600, 2)) . '&nbsp;h</b>', 'duration' => '<b>' . sprintf('%.2f', round($timeSum / 3600, 2)) . '&nbsp;h</b>',
'room' => '', 'location' => '',
'shift_info' => '', 'shift_info' => '',
'comment' => '', 'comment' => '',
'actions' => '', 'actions' => '',
@ -413,7 +413,7 @@ function User_view_myshifts(
$myshifts_table[] = [ $myshifts_table[] = [
'date' => '<b>' . ($goodie_tshirt ? __('Your t-shirt score') : __('Your goodie score')) . '&trade;:</b>', 'date' => '<b>' . ($goodie_tshirt ? __('Your t-shirt score') : __('Your goodie score')) . '&trade;:</b>',
'duration' => '<b>' . $tshirt_score . '</b>', 'duration' => '<b>' . $tshirt_score . '</b>',
'room' => '', 'location' => '',
'shift_info' => '', 'shift_info' => '',
'comment' => '', 'comment' => '',
'actions' => '', 'actions' => '',
@ -451,7 +451,7 @@ function User_view_worklog(Worklog $worklog, $admin_user_worklog_privilege)
return [ return [
'date' => icon('calendar-event') . date(__('Y-m-d'), $worklog->worked_at->timestamp), 'date' => icon('calendar-event') . date(__('Y-m-d'), $worklog->worked_at->timestamp),
'duration' => sprintf('%.2f', $worklog->hours) . ' h', 'duration' => sprintf('%.2f', $worklog->hours) . ' h',
'room' => '', 'location' => '',
'shift_info' => __('Work log entry'), 'shift_info' => __('Work log entry'),
'comment' => $worklog->comment . '<br>' 'comment' => $worklog->comment . '<br>'
. sprintf( . sprintf(
@ -515,7 +515,7 @@ function User_view(
$myshifts_table = div('table-responsive', table([ $myshifts_table = div('table-responsive', table([
'date' => __('Day & Time'), 'date' => __('Day & Time'),
'duration' => __('Duration'), 'duration' => __('Duration'),
'room' => __('Location'), 'location' => __('Location'),
'shift_info' => __('Name & Workmates'), 'shift_info' => __('Name & Workmates'),
'comment' => __('worklog.comment'), 'comment' => __('worklog.comment'),
'actions' => __('Action'), 'actions' => __('Action'),

View File

@ -266,10 +266,10 @@ msgstr "Arbeitseinsatz erfolgreich bearbeitet."
msgid "worklog.delete.success" msgid "worklog.delete.success"
msgstr "Arbeitseinsatz erfolgreich gelöscht." msgstr "Arbeitseinsatz erfolgreich gelöscht."
msgid "room.edit.success" msgid "location.edit.success"
msgstr "Ort erfolgreich bearbeitet." msgstr "Ort erfolgreich bearbeitet."
msgid "room.delete.success" msgid "location.delete.success"
msgstr "Ort erfolgreich gelöscht." msgstr "Ort erfolgreich gelöscht."
msgid "validation.name.exists" msgid "validation.name.exists"

View File

@ -1565,7 +1565,7 @@ msgstr "Minuten vor Talk beginn hinzufügen"
msgid "schedule.minutes-after" msgid "schedule.minutes-after"
msgstr "Minuten nach Talk ende hinzufügen" msgstr "Minuten nach Talk ende hinzufügen"
msgid "schedule.import.rooms.add" msgid "schedule.import.locations.add"
msgstr "Neue Orte" msgstr "Neue Orte"
msgid "schedule.import.shifts.add" msgid "schedule.import.shifts.add"
@ -1583,7 +1583,7 @@ msgstr "Zeit"
msgid "schedule.import.shift.type" msgid "schedule.import.shift.type"
msgstr "Typ" msgstr "Typ"
msgid "schedule.import.shift.room" msgid "schedule.import.shift.location"
msgstr "Ort" msgstr "Ort"
msgid "shifts_history.schedule" msgid "shifts_history.schedule"
@ -1964,22 +1964,22 @@ msgstr "Wenn ausgewählt, können nur Admins und Mitglieder des Engeltyps auf de
msgid "registration.register" msgid "registration.register"
msgstr "Registrieren" msgstr "Registrieren"
msgid "room.rooms" msgid "location.locations"
msgstr "Orte" msgstr "Orte"
msgid "room.map_url" msgid "location.map_url"
msgstr "Karte" msgstr "Karte"
msgid "room.required_angels" msgid "location.required_angels"
msgstr "Benötigte Engel" msgstr "Benötigte Engel"
msgid "room.map_url.info" msgid "location.map_url.info"
msgstr "Die Karte wird auf der Ort-Seite als iframe eingebettet." msgstr "Die Karte wird auf der Ort-Seite als iframe eingebettet."
msgid "room.create.title" msgid "location.create.title"
msgstr "Ort erstellen" msgstr "Ort erstellen"
msgid "room.edit.title" msgid "location.edit.title"
msgstr "Ort bearbeiten" msgstr "Ort bearbeiten"
msgid "event.day" msgid "event.day"

View File

@ -265,10 +265,10 @@ msgstr "Work log successfully updated."
msgid "worklog.delete.success" msgid "worklog.delete.success"
msgstr "Work log successfully deleted." msgstr "Work log successfully deleted."
msgid "room.edit.success" msgid "location.edit.success"
msgstr "Location edited successfully." msgstr "Location edited successfully."
msgid "room.delete.success" msgid "location.delete.success"
msgstr "Location successfully deleted." msgstr "Location successfully deleted."
msgid "validation.name.exists" msgid "validation.name.exists"

View File

@ -133,7 +133,7 @@ msgstr "Add minutes after talk ends"
msgid "schedule.import.request_error" msgid "schedule.import.request_error"
msgstr "Unable to load schedule." msgstr "Unable to load schedule."
msgid "schedule.import.rooms.add" msgid "schedule.import.locations.add"
msgstr "Locations to create" msgstr "Locations to create"
msgid "schedule.import.shifts.add" msgid "schedule.import.shifts.add"
@ -154,7 +154,7 @@ msgstr "Type"
msgid "title.title" msgid "title.title"
msgstr "Title" msgstr "Title"
msgid "schedule.import.shift.room" msgid "schedule.import.shift.location"
msgstr "Location" msgstr "Location"
msgid "shifts_history.schedule" msgid "shifts_history.schedule"
@ -552,22 +552,22 @@ msgstr "If checked only admins and members of the angeltype "
msgid "registration.register" msgid "registration.register"
msgstr "Register" msgstr "Register"
msgid "room.rooms" msgid "location.locations"
msgstr "Locations" msgstr "Locations"
msgid "room.map_url" msgid "location.map_url"
msgstr "Map" msgstr "Map"
msgid "room.required_angels" msgid "location.required_angels"
msgstr "Required angels" msgstr "Required angels"
msgid "room.map_url.info" msgid "location.map_url.info"
msgstr "The map will be embedded on the location page as an iframe." msgstr "The map will be embedded on the location page as an iframe."
msgid "room.create.title" msgid "location.create.title"
msgstr "Create location" msgstr "Create location"
msgid "room.edit.title" msgid "location.edit.title"
msgstr "Edit location" msgstr "Edit location"
msgid "event.day" msgid "event.day"

View File

View File

@ -1,40 +1,40 @@
{% extends 'admin/rooms/index.twig' %} {% extends 'admin/locations/index.twig' %}
{% import 'macros/base.twig' as m %} {% import 'macros/base.twig' as m %}
{% import 'macros/form.twig' as f %} {% import 'macros/form.twig' as f %}
{% block title %}{{ room ? __('room.edit.title') : __('room.create.title') }}{% endblock %} {% block title %}{{ location ? __('location.edit.title') : __('location.create.title') }}{% endblock %}
{% block row_content %} {% block row_content %}
<form method="post"> <form method="post">
{{ csrf() }} {{ csrf() }}
{{ f.hidden('id', room ? room.id : '') }} {{ f.hidden('id', location ? location.id : '') }}
<div class="row"> <div class="row">
<div class="col-lg-6"> <div class="col-lg-6">
{{ f.input('name', __('general.name'), { {{ f.input('name', __('general.name'), {
'required': true, 'required': true,
'required_icon': true, 'required_icon': true,
'value': f.formData('room', room ? room.name : ''), 'value': f.formData('location', location ? location.name : ''),
}) }} }) }}
{{ f.input('dect', __('general.dect'), { {{ f.input('dect', __('general.dect'), {
'value': f.formData('dect', room ? room.dect : ''), 'value': f.formData('dect', location ? location.dect : ''),
}) }} }) }}
{{ f.input('map_url', __('room.map_url'), { {{ f.input('map_url', __('location.map_url'), {
'type': 'url', 'type': 'url',
'value': f.formData('map_url', room ? room.map_url : ''), 'value': f.formData('map_url', location ? location.map_url : ''),
'info': __('room.map_url.info'), 'info': __('location.map_url.info'),
}) }} }) }}
{{ f.textarea('description', __('general.description'), { {{ f.textarea('description', __('general.description'), {
'value': f.formData('description', room ? room.description : ''), 'value': f.formData('description', location ? location.description : ''),
'rows': 5, 'rows': 5,
'info': __('form.markdown') 'info': __('form.markdown')
}) }} }) }}
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<h4>{{ __('room.required_angels') }}</h4> <h4>{{ __('location.required_angels') }}</h4>
{% for types in angel_types.chunk(3) %} {% for types in angel_types.chunk(3) %}
<div class="row"> <div class="row">
{% for angel_type in types %} {% for angel_type in types %}
@ -56,7 +56,7 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="btn-group"> <div class="btn-group">
{{ f.submit(__('form.save'), {'icon_left': 'save'}) }} {{ f.submit(__('form.save'), {'icon_left': 'save'}) }}
{% if room %} {% if location %}
{{ f.submit(__('form.delete'), {'name': 'delete', 'btn_type': 'danger', 'icon_left': 'trash'}) }} {{ f.submit(__('form.delete'), {'name': 'delete', 'btn_type': 'danger', 'icon_left': 'trash'}) }}
{% endif %} {% endif %}
</div> </div>

View File

@ -2,19 +2,19 @@
{% import 'macros/base.twig' as m %} {% import 'macros/base.twig' as m %}
{% import 'macros/form.twig' as f %} {% import 'macros/form.twig' as f %}
{% block title %}{{ __('room.rooms') }}{% endblock %} {% block title %}{{ __('location.locations') }}{% endblock %}
{% block content %} {% block content %}
<div class="container"> <div class="container">
<h1> <h1>
{% if not is_index|default(false) %} {% if not is_index|default(false) %}
{{ m.button(m.icon('chevron-left'), room ? url('/rooms', {'action': 'view', 'room_id': room.id}) : url('/admin/rooms'), 'secondary', 'sm') }} {{ m.button(m.icon('chevron-left'), location ? url('/locations', {'action': 'view', 'location_id': location.id}) : url('/admin/locations'), 'secondary', 'sm') }}
{% endif %} {% endif %}
{{ block('title') }} {{ block('title') }}
{% if is_index|default(false) %} {% if is_index|default(false) %}
{{ m.button(m.icon('plus-lg'), url('/admin/rooms/edit'), 'secondary') }} {{ m.button(m.icon('plus-lg'), url('/admin/locations/edit'), 'secondary') }}
{% endif %} {% endif %}
</h1> </h1>
@ -30,33 +30,33 @@
<tr> <tr>
<th>{{ __('general.name') }}</th> <th>{{ __('general.name') }}</th>
<th>{{ __('general.dect') }}</th> <th>{{ __('general.dect') }}</th>
<th>{{ __('room.map_url') }}</th> <th>{{ __('location.map_url') }}</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for room in rooms %} {% for location in locations %}
<tr> <tr>
<td> <td>
{{ m.icon('pin-map-fill') }} {{ m.icon('pin-map-fill') }}
<a href="{{ url('/rooms', {'action': 'view', 'room_id': room.id}) }}"> <a href="{{ url('/locations', {'action': 'view', 'location_id': location.id}) }}">
{{ room.name }} {{ location.name }}
</a> </a>
</td> </td>
<td>{{ m.iconBool(room.dect) }}</td> <td>{{ m.iconBool(location.dect) }}</td>
<td>{{ m.iconBool(room.map_url) }}</td> <td>{{ m.iconBool(location.map_url) }}</td>
<td> <td>
<div class="d-flex ms-auto"> <div class="d-flex ms-auto">
{{ m.button(m.icon('pencil'), url('admin/rooms/edit/' ~ room.id), null, 'sm', __('form.edit')) }} {{ m.button(m.icon('pencil'), url('admin/locations/edit/' ~ location.id), null, 'sm', __('form.edit')) }}
<form method="post" class="ps-1"> <form method="post" class="ps-1">
{{ csrf() }} {{ csrf() }}
{{ f.hidden('id', room.id) }} {{ f.hidden('id', location.id) }}
{{ f.button(m.icon('trash'), {'title': __('form.delete'), 'name': 'delete', 'type': 'submit', 'btn_type': 'danger', 'size': 'sm'}) }} {{ f.button(m.icon('trash'), {'title': __('form.delete'), 'name': 'delete', 'type': 'submit', 'btn_type': 'danger', 'size': 'sm'}) }}
</form> </form>

View File

@ -14,8 +14,8 @@
<div class="col-lg-12"> <div class="col-lg-12">
<p>{{ __('schedule.import.load.info', [schedule.conference.title, schedule.version]) }}</p> <p>{{ __('schedule.import.load.info', [schedule.conference.title, schedule.version]) }}</p>
<h2>{{ __('schedule.import.rooms.add') }}</h2> <h2>{{ __('schedule.import.locations.add') }}</h2>
{{ _self.roomsTable(rooms.add) }} {{ _self.locationsTable(locations.add) }}
<h2>{{ __('schedule.import.shifts.add') }}</h2> <h2>{{ __('schedule.import.shifts.add') }}</h2>
{{ _self.shiftsTable(shifts.add) }} {{ _self.shiftsTable(shifts.add) }}
@ -32,7 +32,7 @@
{% endblock %} {% endblock %}
{% macro roomsTable(rooms) %} {% macro locationsTable(locations) %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
@ -42,9 +42,9 @@
</thead> </thead>
<tbody> <tbody>
{% for room in rooms %} {% for location in locations %}
<tr> <tr>
<td>{{ room.name }}</td> <td>{{ location.name }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -60,7 +60,7 @@
<th>{{ __('schedule.import.shift.dates') }}</th> <th>{{ __('schedule.import.shift.dates') }}</th>
<th>{{ __('schedule.import.shift.type') }}</th> <th>{{ __('schedule.import.shift.type') }}</th>
<th>{{ __('title.title') }}</th> <th>{{ __('title.title') }}</th>
<th>{{ __('schedule.import.shift.room') }}</th> <th>{{ __('schedule.import.shift.location') }}</th>
</tr> </tr>
</thead> </thead>

View File

@ -13,7 +13,7 @@ DTEND:{{ entry.shift.end.utc().format(dateFormat) }}
STATUS:CONFIRMED STATUS:CONFIRMED
TRANSP:OPAQUE TRANSP:OPAQUE
SUMMARY:{{ (entry.shift.shiftType.name ~ ' (' ~ entry.shift.title ~ ')') | replace(replacement) | raw }} SUMMARY:{{ (entry.shift.shiftType.name ~ ' (' ~ entry.shift.title ~ ')') | replace(replacement) | raw }}
LOCATION:{{ entry.shift.room.name | replace(replacement) | raw }} LOCATION:{{ entry.shift.location.name | replace(replacement) | raw }}
DESCRIPTION:{{ DESCRIPTION:{{
( (
entry.shift.shiftType.description entry.shift.shiftType.description

View File

@ -8,7 +8,7 @@
{{ name }} {{ name }}
{{ title }} {{ title }}
{{ start.format(__('Y-m-d H:i')) }} - {{ end.format(__('Y-m-d H:i')) }} {{ start.format(__('Y-m-d H:i')) }} - {{ end.format(__('Y-m-d H:i')) }}
{{ room.name }} {{ location.name }}
{% if start <= date() and not freeloaded %} {% if start <= date() and not freeloaded %}
{{ __('notification.shift.deleted.worklog') }} {{ __('notification.shift.deleted.worklog') }}

View File

@ -66,7 +66,7 @@
<div class="collapse show d-print-none" id="collapseShiftsFilterSelect"> <div class="collapse show d-print-none" id="collapseShiftsFilterSelect">
<div class="row"> <div class="row">
<div class="col col-12 col-sm-4 col-md-12 col-lg-5 col-xl-4 col-xxl-4">%room_select%</div> <div class="col col-12 col-sm-4 col-md-12 col-lg-5 col-xl-4 col-xxl-4">%location_select%</div>
<div class="col col-12 col-sm-5 col-md-12 col-lg-7 col-xl-5 col-xxl-4">%type_select%</div> <div class="col col-12 col-sm-5 col-md-12 col-lg-7 col-xl-5 col-xxl-4">%type_select%</div>
<div class="col col-12 col-sm-3 col-md-12 col-lg-5 col-xl-3 col-xxl-4">%filled_select%</div> <div class="col col-12 col-sm-3 col-md-12 col-lg-5 col-xl-3 col-xxl-4">%filled_select%</div>
</div> </div>

View File

@ -12,23 +12,23 @@ use Engelsystem\Http\Request;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Engelsystem\Http\Validation\Validator; use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
class RoomsController extends BaseController class LocationsController extends BaseController
{ {
use HasUserNotifications; use HasUserNotifications;
/** @var array<string> */ /** @var array<string> */
protected array $permissions = [ protected array $permissions = [
'admin_rooms', 'admin_locations',
]; ];
public function __construct( public function __construct(
protected LoggerInterface $log, protected LoggerInterface $log,
protected Room $room, protected Location $location,
protected Redirector $redirect, protected Redirector $redirect,
protected Response $response protected Response $response
) { ) {
@ -36,31 +36,31 @@ class RoomsController extends BaseController
public function index(): Response public function index(): Response
{ {
$rooms = $this->room $locations = $this->location
->orderBy('name') ->orderBy('name')
->get(); ->get();
return $this->response->withView( return $this->response->withView(
'admin/rooms/index', 'admin/locations/index',
['rooms' => $rooms, 'is_index' => true] ['locations' => $locations, 'is_index' => true]
); );
} }
public function edit(Request $request): Response public function edit(Request $request): Response
{ {
$roomId = (int) $request->getAttribute('room_id'); $locationId = (int) $request->getAttribute('location_id');
$room = $this->room->find($roomId); $location = $this->location->find($locationId);
return $this->showEdit($room); return $this->showEdit($location);
} }
public function save(Request $request): Response public function save(Request $request): Response
{ {
$roomId = (int) $request->getAttribute('room_id'); $locationId = (int) $request->getAttribute('location_id');
/** @var Room $room */ /** @var Location $location */
$room = $this->room->findOrNew($roomId); $location = $this->location->findOrNew($locationId);
/** @var Collection|AngelType[] $angelTypes */ /** @var Collection|AngelType[] $angelTypes */
$angelTypes = AngelType::all(); $angelTypes = AngelType::all();
$validation = []; $validation = [];
@ -82,17 +82,17 @@ class RoomsController extends BaseController
] + $validation ] + $validation
); );
if (Room::whereName($data['name'])->where('id', '!=', $room->id)->exists()) { if (Location::whereName($data['name'])->where('id', '!=', $location->id)->exists()) {
throw new ValidationException((new Validator())->addErrors(['name' => ['validation.name.exists']])); throw new ValidationException((new Validator())->addErrors(['name' => ['validation.name.exists']]));
} }
$room->name = $data['name']; $location->name = $data['name'];
$room->description = $data['description']; $location->description = $data['description'];
$room->dect = $data['dect']; $location->dect = $data['dect'];
$room->map_url = $data['map_url']; $location->map_url = $data['map_url'];
$room->save(); $location->save();
$room->neededAngelTypes()->getQuery()->delete(); $location->neededAngelTypes()->getQuery()->delete();
$angelsInfo = ''; $angelsInfo = '';
foreach ($angelTypes as $angelType) { foreach ($angelTypes as $angelType) {
@ -103,7 +103,7 @@ class RoomsController extends BaseController
$neededAngelType = new NeededAngelType(); $neededAngelType = new NeededAngelType();
$neededAngelType->room()->associate($room); $neededAngelType->location()->associate($location);
$neededAngelType->angelType()->associate($angelType); $neededAngelType->angelType()->associate($angelType);
$neededAngelType->count = $data['angel_type_' . $angelType->id]; $neededAngelType->count = $data['angel_type_' . $angelType->id];
@ -116,17 +116,17 @@ class RoomsController extends BaseController
$this->log->info( $this->log->info(
'Updated location "{name}": {description} {dect} {map_url} {angels}', 'Updated location "{name}": {description} {dect} {map_url} {angels}',
[ [
'name' => $room->name, 'name' => $location->name,
'description' => $room->description, 'description' => $location->description,
'dect' => $room->dect, 'dect' => $location->dect,
'map_url' => $room->map_url, 'map_url' => $location->map_url,
'angels' => $angelsInfo, 'angels' => $angelsInfo,
] ]
); );
$this->addNotification('room.edit.success'); $this->addNotification('location.edit.success');
return $this->redirect->to('/admin/rooms'); return $this->redirect->to('/admin/locations');
} }
public function delete(Request $request): Response public function delete(Request $request): Response
@ -136,9 +136,9 @@ class RoomsController extends BaseController
'delete' => 'checked', 'delete' => 'checked',
]); ]);
$room = $this->room->findOrFail($data['id']); $location = $this->location->findOrFail($data['id']);
$shifts = $room->shifts; $shifts = $location->shifts;
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
foreach ($shift->shiftEntries as $entry) { foreach ($shift->shiftEntries as $entry) {
event('shift.entry.deleting', [ event('shift.entry.deleting', [
@ -148,27 +148,31 @@ class RoomsController extends BaseController
'name' => $shift->shiftType->name, 'name' => $shift->shiftType->name,
'title' => $shift->title, 'title' => $shift->title,
'type' => $entry->angelType->name, 'type' => $entry->angelType->name,
'room' => $room, 'location' => $location,
'freeloaded' => $entry->freeloaded, 'freeloaded' => $entry->freeloaded,
]); ]);
} }
} }
$room->delete(); $location->delete();
$this->log->info('Deleted location {location}', ['location' => $room->name]); $this->log->info('Deleted location {location}', ['location' => $location->name]);
$this->addNotification('room.delete.success'); $this->addNotification('location.delete.success');
return $this->redirect->to('/admin/rooms'); return $this->redirect->to('/admin/locations');
} }
protected function showEdit(?Room $room): Response protected function showEdit(?Location $location): Response
{ {
$angeltypes = AngelType::all() $angeltypes = AngelType::all()
->sortBy('name'); ->sortBy('name');
return $this->response->withView( return $this->response->withView(
'admin/rooms/edit', 'admin/locations/edit',
['room' => $room, 'angel_types' => $angeltypes, 'needed_angel_types' => $room?->neededAngelTypes] [
'location' => $location,
'angel_types' => $angeltypes,
'needed_angel_types' => $location?->neededAngelTypes,
]
); );
} }
} }

View File

@ -95,12 +95,12 @@ class FeedController extends BaseController
// Talk URL // Talk URL
'URL' => $shift->url, 'URL' => $shift->url,
// Room id // Location (room) id
'RID' => $shift->room->id, 'RID' => $shift->location->id,
// Room name // Location (room) name
'Name' => $shift->room->name, 'Name' => $shift->location->name,
// Location map url // Location map url
'map_url' => $shift->room->map_url, 'map_url' => $shift->location->map_url,
// Start timestamp // Start timestamp
/** @deprecated start_date should be used */ /** @deprecated start_date should be used */
@ -159,7 +159,7 @@ class FeedController extends BaseController
->shiftEntries() ->shiftEntries()
->leftJoin('shifts', 'shifts.id', 'shift_entries.shift_id') ->leftJoin('shifts', 'shifts.id', 'shift_entries.shift_id')
->orderBy('shifts.start') ->orderBy('shifts.start')
->with(['shift', 'shift.room', 'shift.shiftType']) ->with(['shift', 'shift.location', 'shift.shiftType'])
->get(['*', 'shift_entries.id']); ->get(['*', 'shift_entries.id']);
} }
} }

View File

@ -132,7 +132,7 @@ class Controller extends BaseController
] + $userTshirtSizes, ] + $userTshirtSizes,
'locales' => ['type' => 'gauge', 'help' => 'The locales users have configured'] + $userLocales, 'locales' => ['type' => 'gauge', 'help' => 'The locales users have configured'] + $userLocales,
'themes' => ['type' => 'gauge', 'help' => 'The themes users have configured'] + $userThemes, 'themes' => ['type' => 'gauge', 'help' => 'The themes users have configured'] + $userThemes,
'rooms' => ['type' => 'gauge', $this->stats->rooms()], 'locations' => ['type' => 'gauge', $this->stats->locations()],
'shifts' => ['type' => 'gauge', $this->stats->shifts()], 'shifts' => ['type' => 'gauge', $this->stats->shifts()],
'announcements' => [ 'announcements' => [
'type' => 'gauge', 'type' => 'gauge',

View File

@ -14,7 +14,7 @@ use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment; use Engelsystem\Models\NewsComment;
use Engelsystem\Models\OAuth; use Engelsystem\Models\OAuth;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\User\License; use Engelsystem\Models\User\License;
use Engelsystem\Models\User\PasswordReset; use Engelsystem\Models\User\PasswordReset;
@ -291,9 +291,9 @@ class Stats
); );
} }
public function rooms(): int public function locations(): int
{ {
return Room::query() return Location::query()
->count(); ->count();
} }

View File

@ -20,7 +20,7 @@ class LegacyMiddleware implements MiddlewareInterface
'admin_event_config', 'admin_event_config',
'angeltypes', 'angeltypes',
'public_dashboard', 'public_dashboard',
'rooms', 'locations',
'shift_entries', 'shift_entries',
'shifts', 'shifts',
'users', 'users',
@ -98,8 +98,8 @@ class LegacyMiddleware implements MiddlewareInterface
case 'admin_event_config': case 'admin_event_config':
list($title, $content) = event_config_edit_controller(); list($title, $content) = event_config_edit_controller();
return [$title, $content]; return [$title, $content];
case 'rooms': case 'locations':
return rooms_controller(); return locations_controller();
case 'user_myshifts': case 'user_myshifts':
$title = myshifts_title(); $title = myshifts_title();
$content = user_myshifts(); $content = user_myshifts();

View File

@ -24,15 +24,15 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property-read Collection|NeededAngelType[] $neededAngelTypes * @property-read Collection|NeededAngelType[] $neededAngelTypes
* @property-read Collection|Shift[] $shifts * @property-read Collection|Shift[] $shifts
* *
* @method static QueryBuilder|Room[] whereId($value) * @method static QueryBuilder|Location[] whereId($value)
* @method static QueryBuilder|Room[] whereName($value) * @method static QueryBuilder|Location[] whereName($value)
* @method static QueryBuilder|Room[] whereMapUrl($value) * @method static QueryBuilder|Location[] whereMapUrl($value)
* @method static QueryBuilder|Room[] whereDect($value) * @method static QueryBuilder|Location[] whereDect($value)
* @method static QueryBuilder|Room[] whereDescription($value) * @method static QueryBuilder|Location[] whereDescription($value)
* @method static QueryBuilder|Room[] whereCreatedAt($value) * @method static QueryBuilder|Location[] whereCreatedAt($value)
* @method static QueryBuilder|Room[] whereUpdatedAt($value) * @method static QueryBuilder|Location[] whereUpdatedAt($value)
*/ */
class Room extends BaseModel class Location extends BaseModel
{ {
use HasFactory; use HasFactory;

View File

@ -6,24 +6,24 @@ namespace Engelsystem\Models\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\BaseModel; use Engelsystem\Models\BaseModel;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\Builder as QueryBuilder;
/** /**
* @property int $id * @property int $id
* @property int|null $room_id * @property int|null $location_id
* @property int|null $shift_id * @property int|null $shift_id
* @property int $angel_type_id * @property int $angel_type_id
* @property int $count * @property int $count
* *
* @property-read Room|null $room * @property-read Location|null $location
* @property-read Shift|null $shift * @property-read Shift|null $shift
* @property-read AngelType $angelType * @property-read AngelType $angelType
* *
* @method static QueryBuilder|NeededAngelType[] whereId($value) * @method static QueryBuilder|NeededAngelType[] whereId($value)
* @method static QueryBuilder|NeededAngelType[] whereRoomId($value) * @method static QueryBuilder|NeededAngelType[] whereLocationId($value)
* @method static QueryBuilder|NeededAngelType[] whereShiftId($value) * @method static QueryBuilder|NeededAngelType[] whereShiftId($value)
* @method static QueryBuilder|NeededAngelType[] whereAngelTypeId($value) * @method static QueryBuilder|NeededAngelType[] whereAngelTypeId($value)
* @method static QueryBuilder|NeededAngelType[] whereCount($value) * @method static QueryBuilder|NeededAngelType[] whereCount($value)
@ -34,21 +34,21 @@ class NeededAngelType extends BaseModel
/** @var array<string, null> default attributes */ /** @var array<string, null> default attributes */
protected $attributes = [ // phpcs:ignore protected $attributes = [ // phpcs:ignore
'room_id' => null, 'location_id' => null,
'shift_id' => null, 'shift_id' => null,
]; ];
/** @var array<string> */ /** @var array<string> */
protected $fillable = [ // phpcs:ignore protected $fillable = [ // phpcs:ignore
'room_id', 'location_id',
'shift_id', 'shift_id',
'angel_type_id', 'angel_type_id',
'count', 'count',
]; ];
public function room(): BelongsTo public function location(): BelongsTo
{ {
return $this->belongsTo(Room::class); return $this->belongsTo(Location::class);
} }
public function shift(): BelongsTo public function shift(): BelongsTo

View File

@ -6,7 +6,7 @@ namespace Engelsystem\Models\Shifts;
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Models\BaseModel; use Engelsystem\Models\BaseModel;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -23,7 +23,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property Carbon $start * @property Carbon $start
* @property Carbon $end * @property Carbon $end
* @property int $shift_type_id * @property int $shift_type_id
* @property int $room_id * @property int $location_id
* @property string $transaction_id * @property string $transaction_id
* @property int $created_by * @property int $created_by
* @property int|null $updated_by * @property int|null $updated_by
@ -34,7 +34,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property-read Schedule $schedule * @property-read Schedule $schedule
* @property-read Collection|ShiftEntry[] $shiftEntries * @property-read Collection|ShiftEntry[] $shiftEntries
* @property-read ShiftType $shiftType * @property-read ShiftType $shiftType
* @property-read Room $room * @property-read Location $location
* @property-read User $createdBy * @property-read User $createdBy
* @property-read User|null $updatedBy * @property-read User|null $updatedBy
* *
@ -45,7 +45,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @method static QueryBuilder|Shift[] whereStart($value) * @method static QueryBuilder|Shift[] whereStart($value)
* @method static QueryBuilder|Shift[] whereEnd($value) * @method static QueryBuilder|Shift[] whereEnd($value)
* @method static QueryBuilder|Shift[] whereShiftTypeId($value) * @method static QueryBuilder|Shift[] whereShiftTypeId($value)
* @method static QueryBuilder|Shift[] whereRoomId($value) * @method static QueryBuilder|Shift[] whereLocationId($value)
* @method static QueryBuilder|Shift[] whereTransactionId($value) * @method static QueryBuilder|Shift[] whereTransactionId($value)
* @method static QueryBuilder|Shift[] whereCreatedBy($value) * @method static QueryBuilder|Shift[] whereCreatedBy($value)
* @method static QueryBuilder|Shift[] whereUpdatedBy($value) * @method static QueryBuilder|Shift[] whereUpdatedBy($value)
@ -70,7 +70,7 @@ class Shift extends BaseModel
/** @var array<string, string> */ /** @var array<string, string> */
protected $casts = [ // phpcs:ignore protected $casts = [ // phpcs:ignore
'shift_type_id' => 'integer', 'shift_type_id' => 'integer',
'room_id' => 'integer', 'location_id' => 'integer',
'created_by' => 'integer', 'created_by' => 'integer',
'updated_by' => 'integer', 'updated_by' => 'integer',
'start' => 'datetime', 'start' => 'datetime',
@ -85,7 +85,7 @@ class Shift extends BaseModel
'start', 'start',
'end', 'end',
'shift_type_id', 'shift_type_id',
'room_id', 'location_id',
'transaction_id', 'transaction_id',
'created_by', 'created_by',
'updated_by', 'updated_by',
@ -111,9 +111,9 @@ class Shift extends BaseModel
return $this->belongsTo(ShiftType::class); return $this->belongsTo(ShiftType::class);
} }
public function room(): BelongsTo public function location(): BelongsTo
{ {
return $this->belongsTo(Room::class); return $this->belongsTo(Location::class);
} }
public function createdBy(): BelongsTo public function createdBy(): BelongsTo

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Controllers\Admin; namespace Engelsystem\Test\Unit\Controllers\Admin;
use Engelsystem\Controllers\Admin\RoomsController; use Engelsystem\Controllers\Admin\LocationsController;
use Engelsystem\Events\EventDispatcher; use Engelsystem\Events\EventDispatcher;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\Exceptions\ValidationException; use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Redirector; use Engelsystem\Http\Redirector;
use Engelsystem\Http\Validation\Validator; use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
@ -19,26 +19,26 @@ use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\Controllers\ControllerTest; use Engelsystem\Test\Unit\Controllers\ControllerTest;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
class RoomsControllerTest extends ControllerTest class LocationsControllerTest extends ControllerTest
{ {
protected Redirector|MockObject $redirect; protected Redirector|MockObject $redirect;
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::__construct * @covers \Engelsystem\Controllers\Admin\LocationsController::__construct
* @covers \Engelsystem\Controllers\Admin\RoomsController::index * @covers \Engelsystem\Controllers\Admin\LocationsController::index
*/ */
public function testIndex(): void public function testIndex(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
Room::factory(5)->create(); Location::factory(5)->create();
$this->response->expects($this->once()) $this->response->expects($this->once())
->method('withView') ->method('withView')
->willReturnCallback(function (string $view, array $data) { ->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('admin/rooms/index', $view); $this->assertEquals('admin/locations/index', $view);
$this->assertTrue($data['is_index'] ?? false); $this->assertTrue($data['is_index'] ?? false);
$this->assertCount(5, $data['rooms'] ?? []); $this->assertCount(5, $data['locations'] ?? []);
return $this->response; return $this->response;
}); });
@ -46,48 +46,52 @@ class RoomsControllerTest extends ControllerTest
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::edit * @covers \Engelsystem\Controllers\Admin\LocationsController::edit
* @covers \Engelsystem\Controllers\Admin\RoomsController::showEdit * @covers \Engelsystem\Controllers\Admin\LocationsController::showEdit
*/ */
public function testEdit(): void public function testEdit(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
/** @var Room $room */ /** @var Location $location */
$room = Room::factory()->create(); $location = Location::factory()->create();
$angelTypes = AngelType::factory(3)->create(); $angelTypes = AngelType::factory(3)->create();
(new NeededAngelType(['room_id' => $room->id, 'angel_type_id' => $angelTypes[0]->id, 'count' => 3]))->save(); (new NeededAngelType([
'location_id' => $location->id,
'angel_type_id' => $angelTypes[0]->id,
'count' => 3,
]))->save();
$this->response->expects($this->once()) $this->response->expects($this->once())
->method('withView') ->method('withView')
->willReturnCallback(function (string $view, array $data) use ($room) { ->willReturnCallback(function (string $view, array $data) use ($location) {
$this->assertEquals('admin/rooms/edit', $view); $this->assertEquals('admin/locations/edit', $view);
$this->assertEquals($room->id, $data['room']?->id); $this->assertEquals($location->id, $data['location']?->id);
$this->assertCount(3, $data['angel_types'] ?? []); $this->assertCount(3, $data['angel_types'] ?? []);
$this->assertCount(1, $data['needed_angel_types'] ?? []); $this->assertCount(1, $data['needed_angel_types'] ?? []);
return $this->response; return $this->response;
}); });
$this->request = $this->request->withAttribute('room_id', 1); $this->request = $this->request->withAttribute('location_id', 1);
$controller->edit($this->request); $controller->edit($this->request);
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::edit * @covers \Engelsystem\Controllers\Admin\LocationsController::edit
* @covers \Engelsystem\Controllers\Admin\RoomsController::showEdit * @covers \Engelsystem\Controllers\Admin\LocationsController::showEdit
*/ */
public function testEditNew(): void public function testEditNew(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
AngelType::factory(3)->create(); AngelType::factory(3)->create();
$this->response->expects($this->once()) $this->response->expects($this->once())
->method('withView') ->method('withView')
->willReturnCallback(function (string $view, array $data) { ->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('admin/rooms/edit', $view); $this->assertEquals('admin/locations/edit', $view);
$this->assertEmpty($data['room'] ?? []); $this->assertEmpty($data['location'] ?? []);
$this->assertCount(3, $data['angel_types'] ?? []); $this->assertCount(3, $data['angel_types'] ?? []);
$this->assertEmpty($data['needed_angel_types'] ?? []); $this->assertEmpty($data['needed_angel_types'] ?? []);
return $this->response; return $this->response;
@ -97,16 +101,16 @@ class RoomsControllerTest extends ControllerTest
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save * @covers \Engelsystem\Controllers\Admin\LocationsController::save
*/ */
public function testSave(): void public function testSave(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
$controller->setValidator(new Validator()); $controller->setValidator(new Validator());
AngelType::factory(3)->create(); AngelType::factory(3)->create();
$this->setExpects($this->redirect, 'to', ['/admin/rooms']); $this->setExpects($this->redirect, 'to', ['/admin/locations']);
$this->request = $this->request->withParsedBody([ $this->request = $this->request->withParsedBody([
'name' => 'Testlocation', 'name' => 'Testlocation',
@ -120,10 +124,10 @@ class RoomsControllerTest extends ControllerTest
$controller->save($this->request); $controller->save($this->request);
$this->assertTrue($this->log->hasInfoThatContains('Updated location')); $this->assertTrue($this->log->hasInfoThatContains('Updated location'));
$this->assertHasNotification('room.edit.success'); $this->assertHasNotification('location.edit.success');
$this->assertCount(1, Room::whereName('Testlocation')->get()); $this->assertCount(1, Location::whereName('Testlocation')->get());
$neededAngelType = NeededAngelType::whereRoomId(1) $neededAngelType = NeededAngelType::whereLocationId(1)
->where('angel_type_id', 2) ->where('angel_type_id', 2)
->where('count', 3) ->where('count', 3)
->get(); ->get();
@ -131,14 +135,14 @@ class RoomsControllerTest extends ControllerTest
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save * @covers \Engelsystem\Controllers\Admin\LocationsController::save
*/ */
public function testSaveUniqueName(): void public function testSaveUniqueName(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
$controller->setValidator(new Validator()); $controller->setValidator(new Validator());
Room::factory()->create(['name' => 'Testlocation']); Location::factory()->create(['name' => 'Testlocation']);
$this->request = $this->request->withParsedBody([ $this->request = $this->request->withParsedBody([
'name' => 'Testlocation', 'name' => 'Testlocation',
@ -149,16 +153,16 @@ class RoomsControllerTest extends ControllerTest
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save * @covers \Engelsystem\Controllers\Admin\LocationsController::save
* @covers \Engelsystem\Controllers\Admin\RoomsController::delete * @covers \Engelsystem\Controllers\Admin\LocationsController::delete
*/ */
public function testSaveDelete(): void public function testSaveDelete(): void
{ {
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
$controller->setValidator(new Validator()); $controller->setValidator(new Validator());
/** @var Room $room */ /** @var Location $location */
$room = Room::factory()->create(); $location = Location::factory()->create();
$this->request = $this->request->withParsedBody([ $this->request = $this->request->withParsedBody([
'id' => '1', 'id' => '1',
@ -166,36 +170,36 @@ class RoomsControllerTest extends ControllerTest
]); ]);
$controller->save($this->request); $controller->save($this->request);
$this->assertEmpty(Room::find($room->id)); $this->assertEmpty(Location::find($location->id));
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\RoomsController::delete * @covers \Engelsystem\Controllers\Admin\LocationsController::delete
*/ */
public function testDelete(): void public function testDelete(): void
{ {
/** @var EventDispatcher|MockObject $dispatcher */ /** @var EventDispatcher|MockObject $dispatcher */
$dispatcher = $this->createMock(EventDispatcher::class); $dispatcher = $this->createMock(EventDispatcher::class);
$this->app->instance('events.dispatcher', $dispatcher); $this->app->instance('events.dispatcher', $dispatcher);
/** @var RoomsController $controller */ /** @var LocationsController $controller */
$controller = $this->app->make(RoomsController::class); $controller = $this->app->make(LocationsController::class);
$controller->setValidator(new Validator()); $controller->setValidator(new Validator());
/** @var Room $room */ /** @var Location $location */
$room = Room::factory()->create(); $location = Location::factory()->create();
/** @var Shift $shift */ /** @var Shift $shift */
$shift = Shift::factory()->create(['room_id' => $room->id, 'start' => Carbon::create()->subHour()]); $shift = Shift::factory()->create(['location_id' => $location->id, 'start' => Carbon::create()->subHour()]);
/** @var User $user */ /** @var User $user */
$user = User::factory()->create(['name' => 'foo', 'email' => 'lorem@ipsum']); $user = User::factory()->create(['name' => 'foo', 'email' => 'lorem@ipsum']);
/** @var ShiftEntry $shiftEntry */ /** @var ShiftEntry $shiftEntry */
ShiftEntry::factory()->create(['shift_id' => $shift->id, 'user_id' => $user->id]); ShiftEntry::factory()->create(['shift_id' => $shift->id, 'user_id' => $user->id]);
$this->setExpects($this->redirect, 'to', ['/admin/rooms'], $this->response); $this->setExpects($this->redirect, 'to', ['/admin/locations'], $this->response);
$dispatcher->expects($this->once()) $dispatcher->expects($this->once())
->method('dispatch') ->method('dispatch')
->willReturnCallback(function (string $event, array $data) use ($room, $user) { ->willReturnCallback(function (string $event, array $data) use ($location, $user) {
$this->assertEquals('shift.entry.deleting', $event); $this->assertEquals('shift.entry.deleting', $event);
$this->assertEquals($room->id, $data['room']->id); $this->assertEquals($location->id, $data['location']->id);
$this->assertEquals($user->id, $data['user']->id); $this->assertEquals($user->id, $data['user']->id);
return []; return [];
@ -205,9 +209,9 @@ class RoomsControllerTest extends ControllerTest
$controller->delete($this->request); $controller->delete($this->request);
$this->assertNull(Room::find($room->id)); $this->assertNull(Location::find($location->id));
$this->assertTrue($this->log->hasInfoThatContains('Deleted location')); $this->assertTrue($this->log->hasInfoThatContains('Deleted location'));
$this->assertHasNotification('room.delete.success'); $this->assertHasNotification('location.delete.success');
} }
public function setUp(): void public function setUp(): void

View File

@ -13,7 +13,7 @@ use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment; use Engelsystem\Models\NewsComment;
use Engelsystem\Models\OAuth; use Engelsystem\Models\OAuth;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\License; use Engelsystem\Models\User\License;
@ -198,17 +198,17 @@ class StatsTest extends TestCase
} }
/** /**
* @covers \Engelsystem\Controllers\Metrics\Stats::rooms * @covers \Engelsystem\Controllers\Metrics\Stats::locations
*/ */
public function testRooms(): void public function testLocations(): void
{ {
(new Room(['name' => 'Location 1']))->save(); (new Location(['name' => 'Location 1']))->save();
(new Room(['name' => 'Second location']))->save(); (new Location(['name' => 'Second location']))->save();
(new Room(['name' => 'Another location']))->save(); (new Location(['name' => 'Another location']))->save();
(new Room(['name' => 'Old location']))->save(); (new Location(['name' => 'Old location']))->save();
$stats = new Stats($this->database); $stats = new Stats($this->database);
$this->assertEquals(4, $stats->rooms()); $this->assertEquals(4, $stats->locations());
} }
/** /**

View File

@ -9,7 +9,7 @@ use Engelsystem\Models\Message;
use Engelsystem\Models\News; use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment; use Engelsystem\Models\NewsComment;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\Schedule; use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\Shifts\ShiftEntry;
@ -42,7 +42,7 @@ class FactoriesTest extends TestCase
[PasswordReset::class], [PasswordReset::class],
[PersonalData::class], [PersonalData::class],
[Question::class], [Question::class],
[Room::class], [Location::class],
[Schedule::class], [Schedule::class],
[ShiftEntry::class], [ShiftEntry::class],
[Settings::class], [Settings::class],
@ -65,7 +65,7 @@ class FactoriesTest extends TestCase
* @covers \Database\Factories\Engelsystem\Models\User\PasswordResetFactory * @covers \Database\Factories\Engelsystem\Models\User\PasswordResetFactory
* @covers \Database\Factories\Engelsystem\Models\User\PersonalDataFactory * @covers \Database\Factories\Engelsystem\Models\User\PersonalDataFactory
* @covers \Database\Factories\Engelsystem\Models\QuestionFactory * @covers \Database\Factories\Engelsystem\Models\QuestionFactory
* @covers \Database\Factories\Engelsystem\Models\RoomFactory * @covers \Database\Factories\Engelsystem\Models\LocationFactory
* @covers \Database\Factories\Engelsystem\Models\Shifts\ScheduleFactory * @covers \Database\Factories\Engelsystem\Models\Shifts\ScheduleFactory
* @covers \Database\Factories\Engelsystem\Models\User\SettingsFactory * @covers \Database\Factories\Engelsystem\Models\User\SettingsFactory
* @covers \Database\Factories\Engelsystem\Models\Shifts\ShiftFactory * @covers \Database\Factories\Engelsystem\Models\Shifts\ShiftFactory

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Test\Unit\Models;
use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Collection;
class LocationTest extends ModelTest
{
/**
* @covers \Engelsystem\Models\Location::shifts
*/
public function testShifts(): void
{
$location = new Location(['name' => 'Test location']);
$location->save();
/** @var Shift $shift */
Shift::factory()->create(['location_id' => 1]);
$location = Location::find(1);
$this->assertCount(1, $location->shifts);
}
/**
* @covers \Engelsystem\Models\Location::neededAngelTypes
*/
public function testNeededAngelTypes(): void
{
/** @var Collection|Location[] $shifts */
$shifts = Location::factory(3)->create();
$this->assertCount(0, Location::find(1)->neededAngelTypes);
(NeededAngelType::factory()->make(['location_id' => $shifts[0]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['location_id' => $shifts[0]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['location_id' => $shifts[1]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['location_id' => $shifts[2]->id, 'shift_id' => null]))->save();
$this->assertCount(2, Location::find(1)->neededAngelTypes);
$this->assertEquals(1, Location::find(1)->neededAngelTypes[0]->id);
$this->assertEquals(2, Location::find(1)->neededAngelTypes[1]->id);
$this->assertEquals(3, Location::find(2)->neededAngelTypes->first()->id);
$this->assertEquals(4, Location::find(3)->neededAngelTypes->first()->id);
}
}

View File

@ -1,50 +0,0 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Test\Unit\Models;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Collection;
class RoomTest extends ModelTest
{
/**
* @covers \Engelsystem\Models\Room::shifts
*/
public function testShifts(): void
{
$room = new Room(['name' => 'Test location']);
$room->save();
/** @var Shift $shift */
Shift::factory()->create(['room_id' => 1]);
$room = Room::find(1);
$this->assertCount(1, $room->shifts);
}
/**
* @covers \Engelsystem\Models\Room::neededAngelTypes
*/
public function testNeededAngelTypes(): void
{
/** @var Collection|Room[] $shifts */
$shifts = Room::factory(3)->create();
$this->assertCount(0, Room::find(1)->neededAngelTypes);
(NeededAngelType::factory()->make(['room_id' => $shifts[0]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['room_id' => $shifts[0]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['room_id' => $shifts[1]->id, 'shift_id' => null]))->save();
(NeededAngelType::factory()->make(['room_id' => $shifts[2]->id, 'shift_id' => null]))->save();
$this->assertCount(2, Room::find(1)->neededAngelTypes);
$this->assertEquals(1, Room::find(1)->neededAngelTypes[0]->id);
$this->assertEquals(2, Room::find(1)->neededAngelTypes[1]->id);
$this->assertEquals(3, Room::find(2)->neededAngelTypes->first()->id);
$this->assertEquals(4, Room::find(3)->neededAngelTypes->first()->id);
}
}

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Models\Shifts; namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Models\AngelType; use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Test\Unit\Models\ModelTest; use Engelsystem\Test\Unit\Models\ModelTest;
@ -13,28 +13,28 @@ use Engelsystem\Test\Unit\Models\ModelTest;
class NeededAngelTypeTest extends ModelTest class NeededAngelTypeTest extends ModelTest
{ {
/** /**
* @covers \Engelsystem\Models\Shifts\NeededAngelType::room * @covers \Engelsystem\Models\Shifts\NeededAngelType::location
* @covers \Engelsystem\Models\Shifts\NeededAngelType::shift * @covers \Engelsystem\Models\Shifts\NeededAngelType::shift
* @covers \Engelsystem\Models\Shifts\NeededAngelType::angelType * @covers \Engelsystem\Models\Shifts\NeededAngelType::angelType
*/ */
public function testShift(): void public function testShift(): void
{ {
/** @var Room $room */ /** @var Location $location */
$room = Room::factory()->create(); $location = Location::factory()->create();
/** @var Shift $shift */ /** @var Shift $shift */
$shift = Shift::factory()->create(); $shift = Shift::factory()->create();
/** @var AngelType $angelType */ /** @var AngelType $angelType */
$angelType = AngelType::factory()->create(); $angelType = AngelType::factory()->create();
$model = new NeededAngelType(); $model = new NeededAngelType();
$model->room()->associate($room); $model->location()->associate($location);
$model->shift()->associate($shift); $model->shift()->associate($shift);
$model->angelType()->associate($angelType); $model->angelType()->associate($angelType);
$model->count = 3; $model->count = 3;
$model->save(); $model->save();
$model = NeededAngelType::find(1); $model = NeededAngelType::find(1);
$this->assertEquals($room->id, $model->room->id); $this->assertEquals($location->id, $model->location->id);
$this->assertEquals($shift->id, $model->shift->id); $this->assertEquals($shift->id, $model->shift->id);
$this->assertEquals($angelType->id, $model->angelType->id); $this->assertEquals($angelType->id, $model->angelType->id);
$this->assertEquals(3, $model->count); $this->assertEquals(3, $model->count);

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Models\Shifts; namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Helpers\Carbon; use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\Room; use Engelsystem\Models\Location;
use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Schedule; use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\ScheduleShift; use Engelsystem\Models\Shifts\ScheduleShift;
@ -20,7 +20,7 @@ class ShiftTest extends ModelTest
{ {
/** /**
* @covers \Engelsystem\Models\Shifts\Shift::shiftType * @covers \Engelsystem\Models\Shifts\Shift::shiftType
* @covers \Engelsystem\Models\Shifts\Shift::room * @covers \Engelsystem\Models\Shifts\Shift::location
* @covers \Engelsystem\Models\Shifts\Shift::createdBy * @covers \Engelsystem\Models\Shifts\Shift::createdBy
* @covers \Engelsystem\Models\Shifts\Shift::updatedBy * @covers \Engelsystem\Models\Shifts\Shift::updatedBy
*/ */
@ -32,8 +32,8 @@ class ShiftTest extends ModelTest
$user2 = User::factory()->create(); $user2 = User::factory()->create();
/** @var ShiftType $shiftType */ /** @var ShiftType $shiftType */
$shiftType = ShiftType::factory()->create(); $shiftType = ShiftType::factory()->create();
/** @var Room $room */ /** @var Location $location */
$room = Room::factory()->create(); $location = Location::factory()->create();
$model = new Shift([ $model = new Shift([
'title' => 'Test shift', 'title' => 'Test shift',
@ -42,7 +42,7 @@ class ShiftTest extends ModelTest
'start' => Carbon::now(), 'start' => Carbon::now(),
'end' => Carbon::now(), 'end' => Carbon::now(),
'shift_type_id' => $shiftType->id, 'shift_type_id' => $shiftType->id,
'room_id' => $room->id, 'location_id' => $location->id,
'transaction_id' => '', 'transaction_id' => '',
'created_by' => $user1->id, 'created_by' => $user1->id,
'updated_by' => $user2->id, 'updated_by' => $user2->id,
@ -52,7 +52,7 @@ class ShiftTest extends ModelTest
$model = Shift::find(1); $model = Shift::find(1);
$this->assertEquals($shiftType->id, $model->shiftType->id); $this->assertEquals($shiftType->id, $model->shiftType->id);
$this->assertEquals($room->id, $model->room->id); $this->assertEquals($location->id, $model->location->id);
$this->assertEquals($user1->id, $model->createdBy->id); $this->assertEquals($user1->id, $model->createdBy->id);
$this->assertEquals($user2->id, $model->updatedBy->id); $this->assertEquals($user2->id, $model->updatedBy->id);
} }
@ -67,10 +67,10 @@ class ShiftTest extends ModelTest
$this->assertCount(0, Shift::find(1)->neededAngelTypes); $this->assertCount(0, Shift::find(1)->neededAngelTypes);
(NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'room_id' => null]))->save(); (NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'location_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'room_id' => null]))->save(); (NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'location_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[1]->id, 'room_id' => null]))->save(); (NeededAngelType::factory()->make(['shift_id' => $shifts[1]->id, 'location_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[2]->id, 'room_id' => null]))->save(); (NeededAngelType::factory()->make(['shift_id' => $shifts[2]->id, 'location_id' => null]))->save();
$this->assertCount(2, Shift::find(1)->neededAngelTypes); $this->assertCount(2, Shift::find(1)->neededAngelTypes);
$this->assertEquals(1, Shift::find(1)->neededAngelTypes[0]->id); $this->assertEquals(1, Shift::find(1)->neededAngelTypes[0]->id);