Added Shift model
This commit is contained in:
parent
1d1618836b
commit
3115870ec4
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Factories\Engelsystem\Models\Shifts;
|
||||
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class ShiftFactory extends Factory
|
||||
{
|
||||
/** @var string */
|
||||
protected $model = Shift::class; // phpcs:ignore
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
$start = $this->faker->dateTimeThisMonth('2 weeks');
|
||||
return [
|
||||
'title' => $this->faker->unique()->text(15),
|
||||
'description' => $this->faker->text(),
|
||||
'url' => $this->faker->url(),
|
||||
'start' => $start,
|
||||
'end' => $this->faker->dateTimeInInterval($start, '+3 hours'),
|
||||
'shift_type_id' => ShiftType::factory(),
|
||||
'room_id' => Room::factory(),
|
||||
'transaction_id' => $this->faker->optional()->uuid(),
|
||||
'created_by' => User::factory(),
|
||||
'updated_by' => $this->faker->optional(.3)->boolean() ? User::factory() : null,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Migrations;
|
||||
|
||||
use Engelsystem\Database\Migration\Migration;
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use stdClass;
|
||||
|
||||
class CreateShiftsTable extends Migration
|
||||
{
|
||||
use ChangesReferences;
|
||||
use Reference;
|
||||
|
||||
/**
|
||||
* Creates the new table, copies the data and drops the old one
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
|
||||
$previous = $this->schema->hasTable('Shifts');
|
||||
if ($previous) {
|
||||
$this->schema->rename('Shifts', 'shifts_old');
|
||||
}
|
||||
|
||||
$this->schema->create('shifts', function (Blueprint $table): void {
|
||||
$table->increments('id');
|
||||
$table->string('title');
|
||||
$table->text('description')->default('');
|
||||
$table->string('url')->default('');
|
||||
$table->dateTime('start')->index();
|
||||
$table->dateTime('end');
|
||||
|
||||
$this->references($table, 'shift_types');
|
||||
$this->references($table, 'rooms');
|
||||
|
||||
$table->uuid('transaction_id')->nullable()->default(null)->index();
|
||||
|
||||
$this->references($table, 'users', 'created_by');
|
||||
$this->references($table, 'users', 'updated_by')->nullable()->default(null);
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
if (!$previous) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var stdClass[] $records */
|
||||
$records = $connection
|
||||
->table('shifts_old')
|
||||
->get();
|
||||
foreach ($records as $record) {
|
||||
$isUpdated = !empty($record->edited_at_timestamp)
|
||||
&& $record->edited_at_timestamp != $record->created_at_timestamp;
|
||||
|
||||
$connection->table('shifts')->insert([
|
||||
'id' => $record->SID,
|
||||
'title' => (string) $record->title,
|
||||
'description' => (string) $record->description,
|
||||
'url' => (string) $record->URL,
|
||||
'start' => Carbon::createFromTimestamp($record->start),
|
||||
'end' => Carbon::createFromTimestamp($record->end),
|
||||
'shift_type_id' => $record->shifttype_id,
|
||||
'room_id' => $record->RID,
|
||||
'transaction_id' => $record->transaction_id,
|
||||
'created_by' => $record->created_by_user_id,
|
||||
'updated_by' => $isUpdated ? $record->edited_by_user_id : null,
|
||||
'created_at' => Carbon::createFromTimestamp($record->created_at_timestamp),
|
||||
'updated_at' => $isUpdated ? Carbon::createFromTimestamp($record->edited_at_timestamp) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->changeReferences(
|
||||
'shifts_old',
|
||||
'SID',
|
||||
'shifts',
|
||||
'id'
|
||||
);
|
||||
|
||||
$this->schema->drop('shifts_old');
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates the previous table, copies the data and drops the new one
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
|
||||
$this->schema->rename('shifts', 'shifts_old');
|
||||
|
||||
$this->schema->create('Shifts', function (Blueprint $table): void {
|
||||
$table->increments('SID');
|
||||
$table->mediumText('title')->nullable()->default(null);
|
||||
$this->references($table, 'shift_types', 'shifttype_id');
|
||||
$table->text('description')->nullable()->default(null);
|
||||
$table->integer('start')->index();
|
||||
$table->integer('end');
|
||||
$this->references($table, 'rooms', 'RID')->default(0);
|
||||
$table->mediumText('URL')->nullable()->default(null);
|
||||
|
||||
$this->references($table, 'users', 'created_by_user_id')->nullable()->default(null);
|
||||
$table->integer('created_at_timestamp');
|
||||
$this->references($table, 'users', 'edited_by_user_id')->nullable()->default(null);
|
||||
$table->integer('edited_at_timestamp');
|
||||
|
||||
$table->uuid('transaction_id')->nullable()->default(null)->index();
|
||||
});
|
||||
|
||||
/** @var stdClass[] $records */
|
||||
$records = $connection
|
||||
->table('shifts_old')
|
||||
->get();
|
||||
$now = Carbon::now()->getTimestamp();
|
||||
foreach ($records as $record) {
|
||||
$createdAt = $record->created_at ? Carbon::make($record->created_at)->getTimestamp() : $now;
|
||||
$updatedAt = $record->updated_at ? Carbon::make($record->updated_at)->getTimestamp() : $createdAt;
|
||||
|
||||
$connection->table('Shifts')->insert([
|
||||
'SID' => $record->id,
|
||||
'title' => $record->title,
|
||||
'shifttype_id' => $record->shift_type_id,
|
||||
'description' => $record->description ?: null,
|
||||
'start' => Carbon::make($record->start)->getTimestamp(),
|
||||
'end' => Carbon::make($record->end)->getTimestamp(),
|
||||
'RID' => $record->room_id,
|
||||
'URL' => $record->url ?: null,
|
||||
'created_by_user_id' => $record->created_by,
|
||||
'created_at_timestamp' => $createdAt,
|
||||
'edited_by_user_id' => $record->updated_by,
|
||||
'edited_at_timestamp' => $updatedAt,
|
||||
'transaction_id' => $record->transaction_id,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->changeReferences(
|
||||
'shifts_old',
|
||||
'id',
|
||||
'Shifts',
|
||||
'SID'
|
||||
);
|
||||
|
||||
$this->schema->drop('shifts_old');
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\UserAngelType;
|
||||
use Engelsystem\ShiftsFilter;
|
||||
|
@ -237,7 +238,7 @@ function angeltype_controller_shiftsFilterDays(AngelType $angeltype)
|
|||
$all_shifts = Shifts_by_angeltype($angeltype);
|
||||
$days = [];
|
||||
foreach ($all_shifts as $shift) {
|
||||
$day = date('Y-m-d', $shift['start']);
|
||||
$day = Carbon::make($shift['start'])->format('Y-m-d');
|
||||
if (!in_array($day, $days)) {
|
||||
$days[] = $day;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\ShiftsFilter;
|
||||
|
||||
/**
|
||||
|
@ -49,6 +48,7 @@ function public_dashboard_controller()
|
|||
$free_shifts_source = Shifts_free(time(), time() + 12 * 60 * 60, $filter);
|
||||
$free_shifts = [];
|
||||
foreach ($free_shifts_source as $shift) {
|
||||
$shift = Shift($shift);
|
||||
$free_shift = public_dashboard_controller_free_shift($shift, $filter);
|
||||
if (count($free_shift['needed_angels']) > 0) {
|
||||
$free_shifts[] = $free_shift;
|
||||
|
@ -64,32 +64,30 @@ function public_dashboard_controller()
|
|||
/**
|
||||
* Gathers information for free shifts to display.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param ShiftsFilter|null $filter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function public_dashboard_controller_free_shift($shift, ShiftsFilter $filter = null)
|
||||
function public_dashboard_controller_free_shift(Shift $shift, ShiftsFilter $filter = null)
|
||||
{
|
||||
$shifttype = ShiftType::find($shift['shifttype_id']);
|
||||
$room = Room::find($shift['RID']);
|
||||
|
||||
// ToDo move to model and return one
|
||||
$free_shift = [
|
||||
'SID' => $shift['SID'],
|
||||
'id' => $shift->id,
|
||||
'style' => 'default',
|
||||
'start' => date('H:i', $shift['start']),
|
||||
'end' => date('H:i', $shift['end']),
|
||||
'duration' => round(($shift['end'] - $shift['start']) / 3600),
|
||||
'shifttype_name' => $shifttype->name,
|
||||
'title' => $shift['title'],
|
||||
'room_name' => $room->name,
|
||||
'needed_angels' => public_dashboard_needed_angels($shift['NeedAngels'], $filter),
|
||||
'start' => $shift->start->format('H:i'),
|
||||
'end' => $shift->end->format('H:i'),
|
||||
'duration' => round(($shift->end->timestamp - $shift->start->timestamp) / 3600),
|
||||
'shifttype_name' => $shift->shiftType->name,
|
||||
'title' => $shift->title,
|
||||
'room_name' => $shift->room->name,
|
||||
'needed_angels' => public_dashboard_needed_angels($shift->neededAngels, $filter),
|
||||
];
|
||||
|
||||
if (time() + 3 * 60 * 60 > $shift['start']) {
|
||||
if (time() + 3 * 60 * 60 > $shift->start->timestamp) {
|
||||
$free_shift['style'] = 'warning';
|
||||
}
|
||||
if (time() > $shift['start']) {
|
||||
if (time() > $shift->start->timestamp) {
|
||||
$free_shift['style'] = 'danger';
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ function room_controller(): array
|
|||
$request = request();
|
||||
$room = load_room();
|
||||
|
||||
$all_shifts = Shifts_by_room($room);
|
||||
$all_shifts = $room->shifts->sortBy('start');
|
||||
$days = [];
|
||||
foreach ($all_shifts as $shift) {
|
||||
$day = date('Y-m-d', $shift['start']);
|
||||
$day = $shift->start->format('Y-m-d');
|
||||
if (!in_array($day, $days)) {
|
||||
$days[] = $day;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Models\UserAngelType;
|
||||
use Engelsystem\ShiftSignupState;
|
||||
|
@ -71,11 +71,11 @@ function shift_entry_create_controller(): array
|
|||
* Sign up for a shift.
|
||||
* Case: Admin
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType|null $angeltype
|
||||
* @return array
|
||||
*/
|
||||
function shift_entry_create_controller_admin($shift, ?AngelType $angeltype): array
|
||||
function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype): array
|
||||
{
|
||||
$signup_user = auth()->user();
|
||||
$request = request();
|
||||
|
@ -100,7 +100,7 @@ function shift_entry_create_controller_admin($shift, ?AngelType $angeltype): arr
|
|||
|
||||
if ($request->hasPostData('submit')) {
|
||||
ShiftEntry_create([
|
||||
'SID' => $shift['SID'],
|
||||
'SID' => $shift->id,
|
||||
'TID' => $angeltype->id,
|
||||
'UID' => $signup_user->id,
|
||||
'Comment' => '',
|
||||
|
@ -120,7 +120,7 @@ function shift_entry_create_controller_admin($shift, ?AngelType $angeltype): arr
|
|||
}
|
||||
|
||||
$angeltypes_select = $angeltypes->pluck('name', 'id')->toArray();
|
||||
$room = Room::find($shift['RID']);
|
||||
$room = $shift->room;
|
||||
return [
|
||||
ShiftEntry_create_title(),
|
||||
ShiftEntry_create_view_admin($shift, $room, $angeltype, $angeltypes_select, $signup_user, $users_select)
|
||||
|
@ -131,11 +131,11 @@ function shift_entry_create_controller_admin($shift, ?AngelType $angeltype): arr
|
|||
* Sign up for a shift.
|
||||
* Case: Supporter
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @return array
|
||||
*/
|
||||
function shift_entry_create_controller_supporter($shift, AngelType $angeltype): array
|
||||
function shift_entry_create_controller_supporter(Shift $shift, AngelType $angeltype): array
|
||||
{
|
||||
$request = request();
|
||||
$signup_user = auth()->user();
|
||||
|
@ -151,7 +151,7 @@ function shift_entry_create_controller_supporter($shift, AngelType $angeltype):
|
|||
|
||||
if ($request->hasPostData('submit')) {
|
||||
ShiftEntry_create([
|
||||
'SID' => $shift['SID'],
|
||||
'SID' => $shift->id,
|
||||
'TID' => $angeltype->id,
|
||||
'UID' => $signup_user->id,
|
||||
'Comment' => '',
|
||||
|
@ -169,7 +169,7 @@ function shift_entry_create_controller_supporter($shift, AngelType $angeltype):
|
|||
$users_select[$u->id] = $u->name;
|
||||
}
|
||||
|
||||
$room = Room::find($shift['RID']);
|
||||
$room = $shift->room;
|
||||
return [
|
||||
ShiftEntry_create_title(),
|
||||
ShiftEntry_create_view_supporter($shift, $room, $angeltype, $signup_user, $users_select)
|
||||
|
@ -204,17 +204,17 @@ function shift_entry_error_message(ShiftSignupState $shift_signup_state)
|
|||
* Sign up for a shift.
|
||||
* Case: User
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @return array
|
||||
*/
|
||||
function shift_entry_create_controller_user($shift, AngelType $angeltype): array
|
||||
function shift_entry_create_controller_user(Shift $shift, AngelType $angeltype): array
|
||||
{
|
||||
$request = request();
|
||||
|
||||
$signup_user = auth()->user();
|
||||
$needed_angeltype = (new AngelType())->forceFill(NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype));
|
||||
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $angeltype->id);
|
||||
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift->id, $angeltype->id);
|
||||
$shift_signup_state = Shift_signup_allowed(
|
||||
$signup_user,
|
||||
$shift,
|
||||
|
@ -233,7 +233,7 @@ function shift_entry_create_controller_user($shift, AngelType $angeltype): array
|
|||
if ($request->hasPostData('submit')) {
|
||||
$comment = strip_request_item_nl('comment');
|
||||
ShiftEntry_create([
|
||||
'SID' => $shift['SID'],
|
||||
'SID' => $shift->id,
|
||||
'TID' => $angeltype->id,
|
||||
'UID' => $signup_user->id,
|
||||
'Comment' => $comment,
|
||||
|
@ -255,7 +255,7 @@ function shift_entry_create_controller_user($shift, AngelType $angeltype): array
|
|||
throw_redirect(shift_link($shift));
|
||||
}
|
||||
|
||||
$room = Room::find($shift['RID']);
|
||||
$room = $shift->room;
|
||||
return [
|
||||
ShiftEntry_create_title(),
|
||||
ShiftEntry_create_view_user($shift, $room, $angeltype, $comment)
|
||||
|
@ -265,16 +265,16 @@ function shift_entry_create_controller_user($shift, AngelType $angeltype): array
|
|||
/**
|
||||
* Link to create a shift entry.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @param array $params
|
||||
* @return string URL
|
||||
*/
|
||||
function shift_entry_create_link($shift, AngelType $angeltype, $params = [])
|
||||
function shift_entry_create_link(Shift $shift, AngelType $angeltype, $params = [])
|
||||
{
|
||||
$params = array_merge([
|
||||
'action' => 'create',
|
||||
'shift_id' => $shift['SID'],
|
||||
'shift_id' => $shift->id,
|
||||
'angeltype_id' => $angeltype->id
|
||||
], $params);
|
||||
return page_link_to('shift_entries', $params);
|
||||
|
@ -283,15 +283,15 @@ function shift_entry_create_link($shift, AngelType $angeltype, $params = [])
|
|||
/**
|
||||
* Link to create a shift entry as admin.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param array $params
|
||||
* @return string URL
|
||||
*/
|
||||
function shift_entry_create_link_admin($shift, $params = [])
|
||||
function shift_entry_create_link_admin(Shift $shift, $params = [])
|
||||
{
|
||||
$params = array_merge([
|
||||
'action' => 'create',
|
||||
'shift_id' => $shift['SID']
|
||||
'shift_id' => $shift->id
|
||||
], $params);
|
||||
return page_link_to('shift_entries', $params);
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ function shift_entry_delete_controller()
|
|||
/**
|
||||
* Link to delete a shift entry.
|
||||
*
|
||||
* @param array $shiftEntry
|
||||
* @param array|Shift $shiftEntry
|
||||
* @param array $params
|
||||
* @return string URL
|
||||
*/
|
||||
|
@ -368,7 +368,7 @@ function shift_entry_delete_link($shiftEntry, $params = [])
|
|||
{
|
||||
$params = array_merge([
|
||||
'action' => 'delete',
|
||||
'shift_entry_id' => $shiftEntry['id']
|
||||
'shift_entry_id' => $shiftEntry['shift_entry_id'] ?? $shiftEntry['id']
|
||||
], $params);
|
||||
return page_link_to('shift_entries', $params);
|
||||
}
|
||||
|
|
|
@ -1,44 +1,45 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\ShiftSignupState;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param array|Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function shift_link($shift)
|
||||
{
|
||||
$parameters = ['action' => 'view'];
|
||||
if (isset($shift['SID'])) {
|
||||
$parameters['shift_id'] = $shift['SID'];
|
||||
if (isset($shift['shift_id']) || isset($shift['id'])) {
|
||||
$parameters['shift_id'] = $shift['shift_id'] ?? $shift['id'];
|
||||
}
|
||||
|
||||
return page_link_to('shifts', $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function shift_delete_link($shift)
|
||||
function shift_delete_link(Shift $shift)
|
||||
{
|
||||
return page_link_to('user_shifts', ['delete_shift' => $shift['SID']]);
|
||||
return page_link_to('user_shifts', ['delete_shift' => $shift->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function shift_edit_link($shift)
|
||||
function shift_edit_link(Shift $shift)
|
||||
{
|
||||
return page_link_to('user_shifts', ['edit_shift' => $shift['SID']]);
|
||||
return page_link_to('user_shifts', ['edit_shift' => $shift->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,8 +61,8 @@ function shift_edit_controller()
|
|||
}
|
||||
$shift_id = $request->input('edit_shift');
|
||||
|
||||
$shift = Shift($shift_id);
|
||||
if (ScheduleShift::whereShiftId($shift['SID'])->first()) {
|
||||
$shift = Shift(Shift::findOrFail($shift_id));
|
||||
if (ScheduleShift::whereShiftId($shift->id)->first()) {
|
||||
warning(__(
|
||||
'This shift was imported from a schedule so some changes will be overwritten with the next import.'
|
||||
));
|
||||
|
@ -81,12 +82,12 @@ function shift_edit_controller()
|
|||
}
|
||||
}
|
||||
|
||||
$shifttype_id = $shift['shifttype_id'];
|
||||
$title = $shift['title'];
|
||||
$description = $shift['description'];
|
||||
$rid = $shift['RID'];
|
||||
$start = $shift['start'];
|
||||
$end = $shift['end'];
|
||||
$shifttype_id = $shift->shift_type_id;
|
||||
$title = $shift->title;
|
||||
$description = $shift->description;
|
||||
$rid = $shift->room_id;
|
||||
$start = $shift->start;
|
||||
$end = $shift->end;
|
||||
|
||||
if ($request->hasPostData('submit')) {
|
||||
// Name/Bezeichnung der Schicht, darf leer sein
|
||||
|
@ -102,33 +103,33 @@ function shift_edit_controller()
|
|||
$rid = $request->input('rid');
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please select a room.'), true);
|
||||
error(__('Please select a room.'));
|
||||
}
|
||||
|
||||
if ($request->has('shifttype_id') && isset($shifttypes[$request->input('shifttype_id')])) {
|
||||
$shifttype_id = $request->input('shifttype_id');
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please select a shifttype.'), true);
|
||||
error(__('Please select a shifttype.'));
|
||||
}
|
||||
|
||||
if ($request->has('start') && $tmp = parse_date('Y-m-d H:i', $request->input('start'))) {
|
||||
if ($request->has('start') && $tmp = DateTime::createFromFormat('Y-m-d H:i', $request->input('start'))) {
|
||||
$start = $tmp;
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please enter a valid starting time for the shifts.'), true);
|
||||
error(__('Please enter a valid starting time for the shifts.'));
|
||||
}
|
||||
|
||||
if ($request->has('end') && $tmp = parse_date('Y-m-d H:i', $request->input('end'))) {
|
||||
if ($request->has('end') && $tmp = DateTime::createFromFormat('Y-m-d H:i', $request->input('end'))) {
|
||||
$end = $tmp;
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please enter a valid ending time for the shifts.'), true);
|
||||
error(__('Please enter a valid ending time for the shifts.'));
|
||||
}
|
||||
|
||||
if ($start >= $end) {
|
||||
$valid = false;
|
||||
error(__('The ending time has to be after the starting time.'), true);
|
||||
error(__('The ending time has to be after the starting time.'));
|
||||
}
|
||||
|
||||
foreach ($needed_angel_types as $needed_angeltype_id => $count) {
|
||||
|
@ -143,20 +144,28 @@ function shift_edit_controller()
|
|||
error(sprintf(
|
||||
__('Please check your input for needed angels of type %s.'),
|
||||
$angeltypes[$needed_angeltype_id]
|
||||
), true);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($valid) {
|
||||
$shift['shifttype_id'] = $shifttype_id;
|
||||
$shift['title'] = $title;
|
||||
$shift['description'] = $description;
|
||||
$shift['RID'] = $rid;
|
||||
$shift['start'] = $start;
|
||||
$shift['end'] = $end;
|
||||
$shift->shift_type_id = $shifttype_id;
|
||||
$shift->title = $title;
|
||||
$shift->description = $description;
|
||||
$shift->room_id = $rid;
|
||||
$shift->start = $start;
|
||||
$shift->end = $end;
|
||||
$shift->updatedBy()->associate(auth()->user());
|
||||
|
||||
// Remove merged data as it is not really part of the model and thus can't be saved
|
||||
unset($shift->shiftEntry);
|
||||
unset($shift->neededAngels);
|
||||
|
||||
$shift->save();
|
||||
|
||||
mail_shift_change(Shift($shift->id), $shift);
|
||||
|
||||
Shift_update($shift);
|
||||
NeededAngelTypes_delete_by_shift($shift_id);
|
||||
$needed_angel_types_info = [];
|
||||
foreach ($needed_angel_types as $type_id => $count) {
|
||||
|
@ -168,16 +177,14 @@ function shift_edit_controller()
|
|||
|
||||
engelsystem_log(
|
||||
'Updated shift \'' . $shifttypes[$shifttype_id] . ', ' . $title
|
||||
. '\' from ' . date('Y-m-d H:i', $start)
|
||||
. ' to ' . date('Y-m-d H:i', $end)
|
||||
. '\' from ' . $start->format('Y-m-d H:i')
|
||||
. ' to ' . $end->format('Y-m-d H:i')
|
||||
. ' with angel types ' . join(', ', $needed_angel_types_info)
|
||||
. ' and description ' . $description
|
||||
);
|
||||
success(__('Shift updated.'));
|
||||
|
||||
throw_redirect(shift_link([
|
||||
'SID' => $shift_id
|
||||
]));
|
||||
throw_redirect(shift_link($shift));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,8 +208,8 @@ function shift_edit_controller()
|
|||
form_select('shifttype_id', __('Shifttype'), $shifttypes, $shifttype_id),
|
||||
form_text('title', __('Title'), $title),
|
||||
form_select('rid', __('Room:'), $rooms, $rid),
|
||||
form_text('start', __('Start:'), date('Y-m-d H:i', $start)),
|
||||
form_text('end', __('End:'), date('Y-m-d H:i', $end)),
|
||||
form_text('start', __('Start:'), $start->format('Y-m-d H:i')),
|
||||
form_text('end', __('End:'), $end->format('Y-m-d H:i')),
|
||||
form_textarea('description', __('Additional description'), $description),
|
||||
form_info('', __('This description is for single shifts, otherwise please use the description in shift type.')),
|
||||
'<h2>' . __('Needed angels') . '</h2>',
|
||||
|
@ -237,27 +244,26 @@ function shift_delete_controller()
|
|||
|
||||
// Schicht löschen bestätigt
|
||||
if ($request->hasPostData('delete')) {
|
||||
$room = Room::find($shift['RID']);
|
||||
foreach ($shift['ShiftEntry'] as $entry) {
|
||||
foreach ($shift->shiftEntry as $entry) {
|
||||
$type = AngelType::find($entry['TID']);
|
||||
event('shift.entry.deleting', [
|
||||
'user' => User::find($entry['user_id']),
|
||||
'start' => Carbon::createFromTimestamp($shift['start']),
|
||||
'end' => Carbon::createFromTimestamp($shift['end']),
|
||||
'name' => $shift['name'],
|
||||
'title' => $shift['title'],
|
||||
'start' => $shift->start,
|
||||
'end' => $shift->end,
|
||||
'name' => $shift->shiftType->name,
|
||||
'title' => $shift->title,
|
||||
'type' => $type->name,
|
||||
'room' => $room,
|
||||
'room' => $shift->room,
|
||||
'freeloaded' => (bool) $entry['freeloaded'],
|
||||
]);
|
||||
}
|
||||
|
||||
Shift_delete($shift_id);
|
||||
$shift->delete();
|
||||
|
||||
engelsystem_log(
|
||||
'Deleted shift ' . $shift['name']
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
'Deleted shift ' . $shift->title . ': ' . $shift->shiftType->name
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
);
|
||||
success(__('Shift deleted.'));
|
||||
throw_redirect(page_link_to('user_shifts'));
|
||||
|
@ -266,12 +272,12 @@ function shift_delete_controller()
|
|||
return page_with_title(shifts_title(), [
|
||||
error(sprintf(
|
||||
__('Do you want to delete the shift %s from %s to %s?'),
|
||||
$shift['name'],
|
||||
date('Y-m-d H:i', $shift['start']),
|
||||
date('H:i', $shift['end'])
|
||||
$shift->shiftType->name,
|
||||
$shift->start->format('Y-m-d H:i'),
|
||||
$shift->end->format('H:i')
|
||||
), true),
|
||||
form([
|
||||
form_hidden('delete_shift', $shift_id),
|
||||
form_hidden('delete_shift', $shift->id),
|
||||
form_submit('delete', __('delete')),
|
||||
]),
|
||||
]);
|
||||
|
@ -299,8 +305,9 @@ function shift_controller()
|
|||
throw_redirect(page_link_to('user_shifts'));
|
||||
}
|
||||
|
||||
$shifttype = ShiftType::find($shift['shifttype_id']);
|
||||
$room = Room::find($shift['RID']);
|
||||
$shifttype = $shift->shiftType;
|
||||
$room = $shift->room;
|
||||
/** @var AngelType[] $angeltypes */
|
||||
$angeltypes = AngelType::all();
|
||||
$user_shifts = Shifts_by_user($user->id);
|
||||
|
||||
|
@ -311,7 +318,7 @@ function shift_controller()
|
|||
continue;
|
||||
}
|
||||
|
||||
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $angeltype->id);
|
||||
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift->id, $angeltype->id);
|
||||
$needed_angeltype = (new AngelType())->forceFill($needed_angeltype);
|
||||
|
||||
$angeltype_signup_state = Shift_signup_allowed(
|
||||
|
@ -328,7 +335,7 @@ function shift_controller()
|
|||
}
|
||||
|
||||
return [
|
||||
$shift['name'],
|
||||
$shift->shiftType->name,
|
||||
Shift_view($shift, $shifttype, $room, $angeltypes, $shift_signup_state)
|
||||
];
|
||||
}
|
||||
|
@ -345,7 +352,7 @@ function shifts_controller()
|
|||
|
||||
return match ($request->input('action')) {
|
||||
'view' => shift_controller(),
|
||||
'next' => shift_next_controller(), // throw_redirect
|
||||
'next' => shift_next_controller(), // throws redirect
|
||||
default => throw_redirect(page_link_to('/')),
|
||||
};
|
||||
}
|
||||
|
@ -359,7 +366,7 @@ function shift_next_controller()
|
|||
throw_redirect(page_link_to('/'));
|
||||
}
|
||||
|
||||
$upcoming_shifts = ShiftEntries_upcoming_for_user(auth()->user()->id);
|
||||
$upcoming_shifts = ShiftEntries_upcoming_for_user(auth()->user());
|
||||
|
||||
if (!empty($upcoming_shifts)) {
|
||||
throw_redirect(shift_link($upcoming_shifts[0]));
|
||||
|
@ -390,19 +397,74 @@ function shifts_json_export_controller()
|
|||
}
|
||||
|
||||
$shifts = load_ical_shifts();
|
||||
foreach ($shifts as $row => $shift) {
|
||||
$shifts[$row]['start_date'] = Carbon::createFromTimestamp($shift['start'])->toRfc3339String();
|
||||
$shifts[$row]['end_date'] = Carbon::createFromTimestamp($shift['end'])->toRfc3339String();
|
||||
$shifts->sortBy('start_date');
|
||||
$timeZone = CarbonTimeZone::create(config('timezone'));
|
||||
|
||||
$shiftsData = [];
|
||||
foreach ($shifts as $shift) {
|
||||
// Data required for the Fahrplan app integration https://github.com/johnjohndoe/engelsystem
|
||||
// See engelsystem-base/src/main/kotlin/info/metadude/kotlin/library/engelsystem/models/Shift.kt
|
||||
$data = [
|
||||
// Name of the shift (type)
|
||||
'name' => $shift->shiftType->name,
|
||||
// Shift / Talk title
|
||||
'title' => $shift->title,
|
||||
// Shift description
|
||||
'description' => $shift->description,
|
||||
|
||||
// Users comment
|
||||
'Comment' => $shift->Comment,
|
||||
|
||||
// Shift id
|
||||
'SID' => $shift->id,
|
||||
// Shift type id
|
||||
'shifttype_id' => $shift->shift_type_id,
|
||||
// Talk URL
|
||||
'URL' => $shift->url,
|
||||
|
||||
// Room name
|
||||
'Name' => $shift->room->name,
|
||||
// Location map url
|
||||
'map_url' => $shift->room->map_url,
|
||||
|
||||
// Start timestamp
|
||||
/** @deprecated start_date should be used */
|
||||
'start' => $shift->start->timestamp,
|
||||
// Start date
|
||||
'start_date' => $shift->start->toRfc3339String(),
|
||||
// End timestamp
|
||||
/** @deprecated end_date should be used */
|
||||
'end' => $shift->end->timestamp,
|
||||
// End date
|
||||
'end_date' => $shift->end->toRfc3339String(),
|
||||
|
||||
// Timezone offset like "+01:00"
|
||||
/** @deprecated should be retrieved from start_date or end_date */
|
||||
'timezone' => $timeZone->toOffsetName(),
|
||||
// The events timezone like "Europe/Berlin"
|
||||
'event_timezone' => $timeZone->getName(),
|
||||
];
|
||||
|
||||
$shiftsData[] = [
|
||||
// Model data
|
||||
...$shift->toArray(),
|
||||
|
||||
// legacy fields (ignoring created / updated (at/by) data)
|
||||
'RID' => $shift->room_id,
|
||||
|
||||
// Fahrplan app required data
|
||||
...$data
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
raw_output(json_encode($shifts));
|
||||
raw_output(json_encode($shiftsData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns users shifts to export.
|
||||
*
|
||||
* @return array
|
||||
* @return Shift[]|Collection
|
||||
*/
|
||||
function load_ical_shifts()
|
||||
{
|
||||
|
|
|
@ -204,9 +204,9 @@ function user_controller()
|
|||
}
|
||||
|
||||
$shifts = Shifts_by_user($user_source->id, auth()->can('user_shifts_admin'));
|
||||
foreach ($shifts as &$shift) {
|
||||
foreach ($shifts as $shift) {
|
||||
// TODO: Move queries to model
|
||||
$shift['needed_angeltypes'] = Db::select(
|
||||
$shift->needed_angeltypes = Db::select(
|
||||
'
|
||||
SELECT DISTINCT `angel_types`.*
|
||||
FROM `ShiftEntry`
|
||||
|
@ -214,9 +214,10 @@ function user_controller()
|
|||
WHERE `ShiftEntry`.`SID` = ?
|
||||
ORDER BY `angel_types`.`name`
|
||||
',
|
||||
[$shift['SID']]
|
||||
[$shift->id]
|
||||
);
|
||||
foreach ($shift['needed_angeltypes'] as &$needed_angeltype) {
|
||||
$neededAngeltypes = $shift->needed_angeltypes;
|
||||
foreach ($neededAngeltypes as &$needed_angeltype) {
|
||||
$needed_angeltype['users'] = Db::select(
|
||||
'
|
||||
SELECT `ShiftEntry`.`freeloaded`, `users`.*
|
||||
|
@ -225,9 +226,10 @@ function user_controller()
|
|||
WHERE `ShiftEntry`.`SID` = ?
|
||||
AND `ShiftEntry`.`TID` = ?
|
||||
',
|
||||
[$shift['SID'], $needed_angeltype['id']]
|
||||
[$shift->id, $needed_angeltype['id']]
|
||||
);
|
||||
}
|
||||
$shift->needed_angeltypes = $neededAngeltypes;
|
||||
}
|
||||
|
||||
if (empty($user_source->api_key)) {
|
||||
|
@ -360,8 +362,8 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
|
|||
$needed_angeltypes = [];
|
||||
$shift_entries = [];
|
||||
foreach ($shifts as $shift) {
|
||||
$needed_angeltypes[$shift['SID']] = [];
|
||||
$shift_entries[$shift['SID']] = [];
|
||||
$needed_angeltypes[$shift->id] = [];
|
||||
$shift_entries[$shift->id] = [];
|
||||
}
|
||||
|
||||
foreach ($shift_entries_source as $shift_entry) {
|
||||
|
@ -371,8 +373,8 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
|
|||
}
|
||||
|
||||
foreach ($needed_angeltypes_source as $needed_angeltype) {
|
||||
if (isset($needed_angeltypes[$needed_angeltype['SID']])) {
|
||||
$needed_angeltypes[$needed_angeltype['SID']][] = $needed_angeltype;
|
||||
if (isset($needed_angeltypes[$needed_angeltype['shift_id']])) {
|
||||
$needed_angeltypes[$needed_angeltype['shift_id']][] = $needed_angeltype;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,7 +391,7 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
|
|||
$filtered_shifts = [];
|
||||
foreach ($shifts as $shift) {
|
||||
$needed_angels_count = 0;
|
||||
foreach ($needed_angeltypes[$shift['SID']] as $needed_angeltype) {
|
||||
foreach ($needed_angeltypes[$shift->id] as $needed_angeltype) {
|
||||
$taken = 0;
|
||||
|
||||
if (
|
||||
|
@ -399,7 +401,7 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
|
|||
continue;
|
||||
}
|
||||
|
||||
foreach ($shift_entries[$shift['SID']] as $shift_entry) {
|
||||
foreach ($shift_entries[$shift->id] as $shift_entry) {
|
||||
if (
|
||||
$needed_angeltype['angel_type_id'] == $shift_entry['TID']
|
||||
&& $shift_entry['freeloaded'] == 0
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Engelsystem\Events\Listener;
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Helpers\Shifts;
|
||||
use Engelsystem\Mail\EngelsystemMailer;
|
||||
use Engelsystem\Models\Room;
|
||||
|
|
|
@ -1,52 +1,53 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
||||
/**
|
||||
* @param array $old_shift
|
||||
* @param array $new_shift
|
||||
*/
|
||||
function mail_shift_change($old_shift, $new_shift)
|
||||
function mail_shift_change(Shift $old_shift, Shift $new_shift)
|
||||
{
|
||||
$users = ShiftEntries_by_shift($old_shift['SID']);
|
||||
$old_room = Room::find($old_shift['RID']);
|
||||
$new_room = Room::find($new_shift['RID']);
|
||||
$users = ShiftEntries_by_shift($old_shift->id);
|
||||
$old_room = $old_shift->room;
|
||||
$new_room = $new_shift->room;
|
||||
|
||||
$noticeable_changes = false;
|
||||
|
||||
$message = __('A Shift you are registered on has changed:');
|
||||
$message .= "\n";
|
||||
|
||||
if ($old_shift['name'] != $new_shift['name']) {
|
||||
$message .= sprintf(__('* Shift type changed from %s to %s'), $old_shift['name'], $new_shift['name']) . "\n";
|
||||
if ($old_shift->shift_type_id != $new_shift->shift_type_id) {
|
||||
$message .= sprintf(
|
||||
__('* Shift type changed from %s to %s'),
|
||||
$old_shift->shiftType->name,
|
||||
$new_shift->shiftType->name
|
||||
) . "\n";
|
||||
$noticeable_changes = true;
|
||||
}
|
||||
|
||||
if ($old_shift['title'] != $new_shift['title']) {
|
||||
$message .= sprintf(__('* Shift title changed from %s to %s'), $old_shift['title'], $new_shift['title']) . "\n";
|
||||
if ($old_shift->title != $new_shift->title) {
|
||||
$message .= sprintf(__('* Shift title changed from %s to %s'), $old_shift->title, $new_shift->title) . "\n";
|
||||
$noticeable_changes = true;
|
||||
}
|
||||
|
||||
if ($old_shift['start'] != $new_shift['start']) {
|
||||
if ($old_shift->start->timestamp != $new_shift->start->timestamp) {
|
||||
$message .= sprintf(
|
||||
__('* Shift Start changed from %s to %s'),
|
||||
date('Y-m-d H:i', $old_shift['start']),
|
||||
date('Y-m-d H:i', $new_shift['start'])
|
||||
$old_shift->start->format('Y-m-d H:i'),
|
||||
$new_shift->start->format('Y-m-d H:i')
|
||||
) . "\n";
|
||||
$noticeable_changes = true;
|
||||
}
|
||||
|
||||
if ($old_shift['end'] != $new_shift['end']) {
|
||||
if ($old_shift->end->timestamp != $new_shift->end->timestamp) {
|
||||
$message .= sprintf(
|
||||
__('* Shift End changed from %s to %s'),
|
||||
date('Y-m-d H:i', $old_shift['end']),
|
||||
date('Y-m-d H:i', $new_shift['end'])
|
||||
$old_shift->end->format('Y-m-d H:i'),
|
||||
$new_shift->end->format('Y-m-d H:i')
|
||||
) . "\n";
|
||||
$noticeable_changes = true;
|
||||
}
|
||||
|
||||
if ($old_shift['RID'] != $new_shift['RID']) {
|
||||
if ($old_shift->room_id != $new_shift->room_id) {
|
||||
$message .= sprintf(__('* Shift Location changed from %s to %s'), $old_room->name, $new_room->name) . "\n";
|
||||
$noticeable_changes = true;
|
||||
}
|
||||
|
@ -59,11 +60,11 @@ function mail_shift_change($old_shift, $new_shift)
|
|||
$message .= "\n";
|
||||
$message .= __('The updated Shift:') . "\n";
|
||||
|
||||
$message .= $new_shift['name'] . "\n";
|
||||
$message .= $new_shift['title'] . "\n";
|
||||
$message .= date('Y-m-d H:i', $new_shift['start']) . ' - ' . date('H:i', $new_shift['end']) . "\n";
|
||||
$message .= $new_shift->shiftType->name . "\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_room->name . "\n\n";
|
||||
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $new_shift['SID']]) . "\n";
|
||||
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $new_shift->id]) . "\n";
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user = (new User())->forceFill($user);
|
||||
|
@ -78,44 +79,36 @@ function mail_shift_change($old_shift, $new_shift)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $shift
|
||||
*/
|
||||
function mail_shift_assign($user, $shift)
|
||||
function mail_shift_assign(User $user, Shift $shift)
|
||||
{
|
||||
if (!$user->settings->email_shiftinfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
$room = Room::find($shift['RID']);
|
||||
$room = $shift->room;
|
||||
|
||||
$message = __('You have been assigned to a Shift:') . "\n";
|
||||
$message .= $shift['name'] . "\n";
|
||||
$message .= $shift['title'] . "\n";
|
||||
$message .= date('Y-m-d H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']) . "\n";
|
||||
$message .= $shift->shiftType->name . "\n";
|
||||
$message .= $shift->title . "\n";
|
||||
$message .= $shift->start->format('Y-m-d H:i') . ' - ' . $shift->end->format('H:i') . "\n";
|
||||
$message .= $room->name . "\n\n";
|
||||
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $shift['SID']]) . "\n";
|
||||
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $shift->id]) . "\n";
|
||||
|
||||
engelsystem_email_to_user($user, __('Assigned to Shift'), $message, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param array $shift
|
||||
*/
|
||||
function mail_shift_removed($user, $shift)
|
||||
function mail_shift_removed(User $user, Shift $shift)
|
||||
{
|
||||
if (!$user->settings->email_shiftinfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
$room = Room::find($shift['RID']);
|
||||
$room = $shift->room;
|
||||
|
||||
$message = __('You have been removed from a Shift:') . "\n";
|
||||
$message .= $shift['name'] . "\n";
|
||||
$message .= $shift['title'] . "\n";
|
||||
$message .= date('Y-m-d H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']) . "\n";
|
||||
$message .= $shift->shiftType->name . "\n";
|
||||
$message .= $shift->title . "\n";
|
||||
$message .= $shift->start->format('Y-m-d H:i') . ' - ' . $shift->end->format('H:i') . "\n";
|
||||
$message .= $room->name . "\n";
|
||||
|
||||
engelsystem_email_to_user($user, __('Removed from Shift'), $message, true);
|
||||
|
|
|
@ -101,8 +101,8 @@ function NeededAngelTypes_by_shift($shiftId)
|
|||
SELECT `NeededAngelTypes`.*, `angel_types`.`name`, `angel_types`.`restricted`
|
||||
FROM `NeededAngelTypes`
|
||||
JOIN `angel_types` ON `angel_types`.`id` = `NeededAngelTypes`.`angel_type_id`
|
||||
JOIN `Shifts` ON `Shifts`.`RID` = `NeededAngelTypes`.`room_id`
|
||||
WHERE `Shifts`.`SID` = ?
|
||||
JOIN `shifts` ON `shifts`.`room_id` = `NeededAngelTypes`.`room_id`
|
||||
WHERE `shifts`.`id` = ?
|
||||
AND `count` > 0
|
||||
ORDER BY `room_id` DESC
|
||||
', [$shiftId]);
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
use Carbon\Carbon;
|
||||
use Engelsystem\Database\Db;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
||||
/**
|
||||
|
@ -60,8 +58,8 @@ function ShiftEntry_create($shift_entry)
|
|||
{
|
||||
$user = User::find($shift_entry['UID']);
|
||||
$shift = Shift($shift_entry['SID']);
|
||||
$shifttype = ShiftType::find($shift['shifttype_id']);
|
||||
$room = Room::find($shift['RID']);
|
||||
$shifttype = $shift->shiftType;
|
||||
$room = $shift->room;
|
||||
$angeltype = AngelType::find($shift_entry['TID']);
|
||||
$result = Db::insert(
|
||||
'
|
||||
|
@ -86,11 +84,11 @@ function ShiftEntry_create($shift_entry)
|
|||
);
|
||||
engelsystem_log(
|
||||
'User ' . User_Nick_render($user, true)
|
||||
. ' signed up for shift ' . $shift['name']
|
||||
. ' signed up for shift ' . $shift->title
|
||||
. ' (' . $shifttype->name . ')'
|
||||
. ' at ' . $room->name
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
. ' as ' . $angeltype->name
|
||||
);
|
||||
mail_shift_assign($user, $shift);
|
||||
|
@ -147,44 +145,43 @@ function ShiftEntry_delete($shiftEntry)
|
|||
|
||||
$signout_user = User::find($shiftEntry['UID']);
|
||||
$shift = Shift($shiftEntry['SID']);
|
||||
$shifttype = ShiftType::find($shift['shifttype_id']);
|
||||
$room = Room::find($shift['RID']);
|
||||
$shifttype = $shift->shiftType;
|
||||
$room = $shift->room;
|
||||
$angeltype = AngelType::find($shiftEntry['TID']);
|
||||
|
||||
engelsystem_log(
|
||||
'Shift signout: ' . User_Nick_render($signout_user, true)
|
||||
. ' from shift ' . $shift['name']
|
||||
. ' from shift ' . $shift->title
|
||||
. ' (' . $shifttype->name . ')'
|
||||
. ' at ' . $room->name
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
. ' as ' . $angeltype->name
|
||||
);
|
||||
|
||||
mail_shift_removed(User::find($shiftEntry['UID']), Shift($shiftEntry['SID']));
|
||||
mail_shift_removed(User::find($shiftEntry['UID']), $shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next (or current) shifts of given user.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param User $user
|
||||
* @return array
|
||||
*/
|
||||
function ShiftEntries_upcoming_for_user($userId)
|
||||
function ShiftEntries_upcoming_for_user(User $user)
|
||||
{
|
||||
return Db::select(
|
||||
'
|
||||
SELECT *
|
||||
SELECT *, shifts.id as shift_id
|
||||
FROM `ShiftEntry`
|
||||
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
|
||||
JOIN `shifts` ON (`shifts`.`id` = `ShiftEntry`.`SID`)
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
|
||||
WHERE `ShiftEntry`.`UID` = ?
|
||||
AND `Shifts`.`end` > ?
|
||||
ORDER BY `Shifts`.`end`
|
||||
AND `shifts`.`end` > NOW()
|
||||
ORDER BY `shifts`.`end`
|
||||
',
|
||||
[
|
||||
$userId,
|
||||
time(),
|
||||
$user->id
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -192,27 +189,26 @@ function ShiftEntries_upcoming_for_user($userId)
|
|||
/**
|
||||
* Returns shifts completed by the given user.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param User $user
|
||||
* @param Carbon|null $sinceTime
|
||||
* @return array
|
||||
*/
|
||||
function ShiftEntries_finished_by_user($userId, Carbon $sinceTime = null)
|
||||
function ShiftEntries_finished_by_user(User $user, Carbon $sinceTime = null)
|
||||
{
|
||||
return Db::select(
|
||||
'
|
||||
SELECT *
|
||||
FROM `ShiftEntry`
|
||||
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
|
||||
JOIN `shifts` ON (`shifts`.`id` = `ShiftEntry`.`SID`)
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
|
||||
WHERE `ShiftEntry`.`UID` = ?
|
||||
AND `Shifts`.`end` < ?
|
||||
AND `shifts`.`end` < NOW()
|
||||
AND `ShiftEntry`.`freeloaded` = 0
|
||||
' . ($sinceTime ? 'AND Shifts.start >= ' . $sinceTime->getTimestamp() : '') . '
|
||||
ORDER BY `Shifts`.`end` desc
|
||||
' . ($sinceTime ? 'AND shifts.start >= "' . $sinceTime->toString() . '"' : '') . '
|
||||
ORDER BY `shifts`.`end` desc
|
||||
',
|
||||
[
|
||||
$userId,
|
||||
time(),
|
||||
$user->id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Engelsystem;
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
|
||||
/**
|
||||
* BO Class that stores all parameters used to filter shifts for users.
|
||||
*
|
||||
|
@ -86,6 +88,14 @@ class ShiftsFilter
|
|||
$this->endTime = $data['endTime'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int unix timestamp
|
||||
*/
|
||||
|
@ -102,6 +112,14 @@ class ShiftsFilter
|
|||
$this->startTime = $startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int unix timestamp
|
||||
*/
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Database\Db;
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Models\UserAngelType;
|
||||
use Engelsystem\ShiftsFilter;
|
||||
use Engelsystem\ShiftSignupState;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @param AngelType $angeltype
|
||||
|
@ -16,18 +17,18 @@ use Engelsystem\ShiftSignupState;
|
|||
function Shifts_by_angeltype(AngelType $angeltype)
|
||||
{
|
||||
return Db::select('
|
||||
SELECT DISTINCT `Shifts`.* FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
SELECT DISTINCT `shifts`.* FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `shifts`.`id`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `NeededAngelTypes`.`angel_type_id` = ?
|
||||
AND `NeededAngelTypes`.`count` > 0
|
||||
AND s.shift_id IS NULL
|
||||
|
||||
UNION
|
||||
|
||||
SELECT DISTINCT `Shifts`.* FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id` = `Shifts`.`RID`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
SELECT DISTINCT `shifts`.* FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id` = `shifts`.`room_id`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `NeededAngelTypes`.`angel_type_id` = ?
|
||||
AND `NeededAngelTypes`.`count` > 0
|
||||
AND NOT s.shift_id IS NULL
|
||||
|
@ -41,31 +42,35 @@ function Shifts_by_angeltype(AngelType $angeltype)
|
|||
* @param int $end timestamp
|
||||
* @param ShiftsFilter|null $filter
|
||||
*
|
||||
* @return array
|
||||
* @return Collection|Shift[]
|
||||
*/
|
||||
function Shifts_free($start, $end, ShiftsFilter $filter = null)
|
||||
{
|
||||
$start = Carbon::createFromTimestamp($start);
|
||||
$end = Carbon::createFromTimestamp($end);
|
||||
|
||||
$shifts = Db::select('
|
||||
SELECT * FROM (
|
||||
SELECT *
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
FROM (
|
||||
SELECT id, start
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE (`end` > ? AND `start` < ?)
|
||||
AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
> (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
> (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`shifts`.`id` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
AND s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
|
||||
UNION
|
||||
|
||||
SELECT *
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
SELECT id, start
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE (`end` > ? AND `start` < ?)
|
||||
AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
> (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
> (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`shifts`.`id` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
AND NOT s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
) AS `tmp`
|
||||
ORDER BY `tmp`.`start`
|
||||
', [
|
||||
|
@ -74,40 +79,29 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
|
|||
$start,
|
||||
$end
|
||||
]);
|
||||
$free_shifts = [];
|
||||
foreach ($shifts as $shift) {
|
||||
$free_shifts[] = Shift($shift['SID']);
|
||||
}
|
||||
return $free_shifts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Room $room
|
||||
* @return array[]
|
||||
*/
|
||||
function Shifts_by_room(Room $room)
|
||||
{
|
||||
return Db::select(
|
||||
'SELECT * FROM `Shifts` WHERE `RID`=? ORDER BY `start`',
|
||||
[$room->id]
|
||||
);
|
||||
$shifts = collect($shifts);
|
||||
|
||||
return Shift::query()
|
||||
->whereIn('id', $shifts->pluck('id')->toArray())
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShiftsFilter $shiftsFilter
|
||||
* @return array[]
|
||||
* @return Shift[]|Collection
|
||||
*/
|
||||
function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
||||
{
|
||||
$sql = '
|
||||
SELECT * FROM (
|
||||
SELECT DISTINCT `Shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
|
||||
FROM `Shifts`
|
||||
JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id`
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
|
||||
FROM `shifts`
|
||||
JOIN `rooms` ON `shifts`.`room_id` = `rooms`.`id`
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `shifts`.`id`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND `start` BETWEEN ? AND ?
|
||||
AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
|
||||
AND `NeededAngelTypes`.`count` > 0
|
||||
|
@ -115,13 +109,13 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
|||
|
||||
UNION
|
||||
|
||||
SELECT DISTINCT `Shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
|
||||
FROM `Shifts`
|
||||
JOIN `rooms` ON `Shifts`.`RID` = `rooms`.`id`
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `Shifts`.`shifttype_id`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
SELECT DISTINCT `shifts`.*, `shift_types`.`name`, `rooms`.`name` AS `room_name`
|
||||
FROM `shifts`
|
||||
JOIN `rooms` ON `shifts`.`room_id` = `rooms`.`id`
|
||||
JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND `start` BETWEEN ? AND ?
|
||||
AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
|
||||
AND `NeededAngelTypes`.`count` > 0
|
||||
|
@ -131,15 +125,22 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
|||
ORDER BY `room_name`, `start`
|
||||
';
|
||||
|
||||
return Db::select(
|
||||
$shiftsData = Db::select(
|
||||
$sql,
|
||||
[
|
||||
$shiftsFilter->getStartTime(),
|
||||
$shiftsFilter->getEndTime(),
|
||||
$shiftsFilter->getStartTime(),
|
||||
$shiftsFilter->getEndTime(),
|
||||
$shiftsFilter->getStart(),
|
||||
$shiftsFilter->getEnd(),
|
||||
$shiftsFilter->getStart(),
|
||||
$shiftsFilter->getEnd(),
|
||||
]
|
||||
);
|
||||
|
||||
$shifts = [];
|
||||
foreach ($shiftsData as $shift) {
|
||||
$shifts[] = (new Shift())->forceFill($shift);
|
||||
}
|
||||
|
||||
return collect($shifts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,69 +152,69 @@ function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
|||
$sql = '
|
||||
SELECT
|
||||
`NeededAngelTypes`.*,
|
||||
`Shifts`.`SID`,
|
||||
`shifts`.`id` AS shift_id,
|
||||
`angel_types`.`id`,
|
||||
`angel_types`.`name`,
|
||||
`angel_types`.`restricted`,
|
||||
`angel_types`.`no_self_signup`
|
||||
FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||
FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`shifts`.`id`
|
||||
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND `start` BETWEEN ? AND ?
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND shifts.`start` BETWEEN ? AND ?
|
||||
AND s.shift_id IS NULL
|
||||
|
||||
UNION
|
||||
|
||||
SELECT
|
||||
`NeededAngelTypes`.*,
|
||||
`Shifts`.`SID`,
|
||||
`shifts`.`id` AS shift_id,
|
||||
`angel_types`.`id`,
|
||||
`angel_types`.`name`,
|
||||
`angel_types`.`restricted`,
|
||||
`angel_types`.`no_self_signup`
|
||||
FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
|
||||
FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
|
||||
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND `start` BETWEEN ? AND ?
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||
AND shifts.`start` BETWEEN ? AND ?
|
||||
AND NOT s.shift_id IS NULL
|
||||
';
|
||||
|
||||
return Db::select(
|
||||
$sql,
|
||||
[
|
||||
$shiftsFilter->getStartTime(),
|
||||
$shiftsFilter->getEndTime(),
|
||||
$shiftsFilter->getStartTime(),
|
||||
$shiftsFilter->getEndTime(),
|
||||
$shiftsFilter->getStart(),
|
||||
$shiftsFilter->getEnd(),
|
||||
$shiftsFilter->getStart(),
|
||||
$shiftsFilter->getEnd(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @return array|null
|
||||
*/
|
||||
function NeededAngeltype_by_Shift_and_Angeltype($shift, AngelType $angeltype)
|
||||
function NeededAngeltype_by_Shift_and_Angeltype(Shift $shift, AngelType $angeltype)
|
||||
{
|
||||
return Db::selectOne(
|
||||
'
|
||||
SELECT
|
||||
`NeededAngelTypes`.*,
|
||||
`Shifts`.`SID`,
|
||||
`shifts`.`id` AS shift_id,
|
||||
`angel_types`.`id`,
|
||||
`angel_types`.`name`,
|
||||
`angel_types`.`restricted`,
|
||||
`angel_types`.`no_self_signup`
|
||||
FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||
FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`shifts`.`id`
|
||||
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`SID`=?
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`id`=?
|
||||
AND `angel_types`.`id`=?
|
||||
AND s.shift_id IS NULL
|
||||
|
||||
|
@ -221,23 +222,23 @@ function NeededAngeltype_by_Shift_and_Angeltype($shift, AngelType $angeltype)
|
|||
|
||||
SELECT
|
||||
`NeededAngelTypes`.*,
|
||||
`Shifts`.`SID`,
|
||||
`shifts`.`id` AS shift_id,
|
||||
`angel_types`.`id`,
|
||||
`angel_types`.`name`,
|
||||
`angel_types`.`restricted`,
|
||||
`angel_types`.`no_self_signup`
|
||||
FROM `Shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
|
||||
FROM `shifts`
|
||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
|
||||
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `Shifts`.`SID`=?
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`id`=?
|
||||
AND `angel_types`.`id`=?
|
||||
AND NOT s.shift_id IS NULL
|
||||
',
|
||||
[
|
||||
$shift['SID'],
|
||||
$shift->id,
|
||||
$angeltype->id,
|
||||
$shift['SID'],
|
||||
$shift->id,
|
||||
$angeltype->id
|
||||
]
|
||||
);
|
||||
|
@ -258,20 +259,20 @@ function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
|||
`ShiftEntry`.`SID`,
|
||||
`ShiftEntry`.`Comment`,
|
||||
`ShiftEntry`.`freeloaded`
|
||||
FROM `Shifts`
|
||||
JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
FROM `shifts`
|
||||
JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
JOIN `users` ON `ShiftEntry`.`UID`=`users`.`id`
|
||||
WHERE `Shifts`.`RID` IN (%s)
|
||||
WHERE `shifts`.`room_id` IN (%s)
|
||||
AND `start` BETWEEN ? AND ?
|
||||
ORDER BY `Shifts`.`start`
|
||||
ORDER BY `shifts`.`start`
|
||||
',
|
||||
implode(',', $shiftsFilter->getRooms())
|
||||
);
|
||||
return Db::select(
|
||||
$sql,
|
||||
[
|
||||
$shiftsFilter->getStartTime(),
|
||||
$shiftsFilter->getEndTime(),
|
||||
$shiftsFilter->getStart(),
|
||||
$shiftsFilter->getEnd(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -279,15 +280,20 @@ function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
|||
/**
|
||||
* Check if a shift collides with other shifts (in time).
|
||||
*
|
||||
* @param array $shift
|
||||
* @param array $shifts
|
||||
* @param Shift $shift
|
||||
* @param Shift[]|Collection $shifts
|
||||
* @return bool
|
||||
*/
|
||||
function Shift_collides($shift, $shifts)
|
||||
function Shift_collides(Shift $shift, $shifts)
|
||||
{
|
||||
foreach ($shifts as $other_shift) {
|
||||
if ($shift['SID'] != $other_shift['SID']) {
|
||||
if (!($shift['start'] >= $other_shift['end'] || $shift['end'] <= $other_shift['start'])) {
|
||||
if ($shift->id != $other_shift->id) {
|
||||
if (
|
||||
!(
|
||||
$shift->start->timestamp >= $other_shift->end->timestamp
|
||||
|| $shift->end->timestamp <= $other_shift->start->timestamp
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -319,17 +325,17 @@ function Shift_free_entries(AngelType $needed_angeltype, $shift_entries)
|
|||
* Check if shift signup is allowed from the end users point of view (no admin like privileges)
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $shift The shift
|
||||
* @param Shift $shift The shift
|
||||
* @param AngelType $angeltype The angeltype to which the user wants to sign up
|
||||
* @param array|null $user_angeltype
|
||||
* @param array|null $user_shifts List of the users shifts
|
||||
* @param SHift[]|Collection|null $user_shifts List of the users shifts
|
||||
* @param AngelType $needed_angeltype
|
||||
* @param array[] $shift_entries
|
||||
* @return ShiftSignupState
|
||||
*/
|
||||
function Shift_signup_allowed_angel(
|
||||
$user,
|
||||
$shift,
|
||||
Shift $shift,
|
||||
AngelType $angeltype,
|
||||
$user_angeltype,
|
||||
$user_shifts,
|
||||
|
@ -342,7 +348,7 @@ function Shift_signup_allowed_angel(
|
|||
return new ShiftSignupState(ShiftSignupState::NOT_ARRIVED, $free_entries);
|
||||
}
|
||||
|
||||
if (config('signup_advance_hours') && $shift['start'] > time() + config('signup_advance_hours') * 3600) {
|
||||
if (config('signup_advance_hours') && $shift->start->timestamp > time() + config('signup_advance_hours') * 3600) {
|
||||
return new ShiftSignupState(ShiftSignupState::NOT_YET, $free_entries);
|
||||
}
|
||||
|
||||
|
@ -352,7 +358,7 @@ function Shift_signup_allowed_angel(
|
|||
|
||||
$signed_up = false;
|
||||
foreach ($user_shifts as $user_shift) {
|
||||
if ($user_shift['SID'] == $shift['SID']) {
|
||||
if ($user_shift->id == $shift->id) {
|
||||
$signed_up = true;
|
||||
break;
|
||||
}
|
||||
|
@ -364,10 +370,10 @@ function Shift_signup_allowed_angel(
|
|||
}
|
||||
|
||||
$shift_post_signup_total_allowed_seconds =
|
||||
(config('signup_post_fraction') * ($shift['end'] - $shift['start']))
|
||||
(config('signup_post_fraction') * ($shift->end->timestamp - $shift->start->timestamp))
|
||||
+ (config('signup_post_minutes') * 60);
|
||||
|
||||
if (time() > $shift['start'] + $shift_post_signup_total_allowed_seconds) {
|
||||
if (time() > $shift->start->timestamp + $shift_post_signup_total_allowed_seconds) {
|
||||
// you can only join if the shift is in future
|
||||
return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries);
|
||||
}
|
||||
|
@ -393,7 +399,7 @@ function Shift_signup_allowed_angel(
|
|||
}
|
||||
|
||||
if (Shift_collides($shift, $user_shifts)) {
|
||||
// you cannot join if user alread joined a parallel or this shift
|
||||
// you cannot join if user already joined a parallel of this shift
|
||||
return new ShiftSignupState(ShiftSignupState::COLLIDES, $free_entries);
|
||||
}
|
||||
|
||||
|
@ -438,14 +444,14 @@ function Shift_signup_allowed_admin(AngelType $needed_angeltype, $shift_entries)
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if an angel can signout from a shift.
|
||||
* Check if an angel can sign out from a shift.
|
||||
*
|
||||
* @param array $shift The shift
|
||||
* @param Shift $shift The shift
|
||||
* @param AngelType $angeltype The angeltype
|
||||
* @param int $signout_user_id The user that was signed up for the shift
|
||||
* @return bool
|
||||
*/
|
||||
function Shift_signout_allowed($shift, AngelType $angeltype, $signout_user_id)
|
||||
function Shift_signout_allowed(Shift $shift, AngelType $angeltype, $signout_user_id)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
|
@ -462,7 +468,7 @@ function Shift_signout_allowed($shift, AngelType $angeltype, $signout_user_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($signout_user_id == $user->id && $shift['start'] > time() + config('last_unsubscribe') * 3600) {
|
||||
if ($signout_user_id == $user->id && $shift->start->timestamp > time() + config('last_unsubscribe') * 3600) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -473,17 +479,17 @@ function Shift_signout_allowed($shift, AngelType $angeltype, $signout_user_id)
|
|||
* Check if an angel can sign up for given shift.
|
||||
*
|
||||
* @param User $signup_user
|
||||
* @param array $shift The shift
|
||||
* @param Shift $shift The shift
|
||||
* @param AngelType $angeltype The angeltype to which the user wants to sign up
|
||||
* @param array|null $user_angeltype
|
||||
* @param array|null $user_shifts List of the users shifts
|
||||
* @param Shift[]|Collection|null $user_shifts List of the users shifts
|
||||
* @param AngelType $needed_angeltype
|
||||
* @param array[] $shift_entries
|
||||
* @return ShiftSignupState
|
||||
*/
|
||||
function Shift_signup_allowed(
|
||||
$signup_user,
|
||||
$shift,
|
||||
Shift $shift,
|
||||
AngelType $angeltype,
|
||||
$user_angeltype,
|
||||
$user_shifts,
|
||||
|
@ -512,179 +518,85 @@ function Shift_signup_allowed(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a shift.
|
||||
*
|
||||
* @param int $shift_id
|
||||
*/
|
||||
function Shift_delete($shift_id)
|
||||
{
|
||||
Db::delete('DELETE FROM `Shifts` WHERE `SID`=?', [$shift_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @return int Updated row count
|
||||
*/
|
||||
function Shift_update($shift)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$shift['name'] = ShiftType::find($shift['shifttype_id'])->name;
|
||||
mail_shift_change(Shift($shift['SID']), $shift);
|
||||
|
||||
return Db::update(
|
||||
'
|
||||
UPDATE `Shifts` SET
|
||||
`shifttype_id` = ?,
|
||||
`start` = ?,
|
||||
`end` = ?,
|
||||
`RID` = ?,
|
||||
`title` = ?,
|
||||
`description` = ?,
|
||||
`URL` = ?,
|
||||
`edited_by_user_id` = ?,
|
||||
`edited_at_timestamp` = ?
|
||||
WHERE `SID` = ?
|
||||
',
|
||||
[
|
||||
$shift['shifttype_id'],
|
||||
$shift['start'],
|
||||
$shift['end'],
|
||||
$shift['RID'],
|
||||
$shift['title'],
|
||||
$shift['description'],
|
||||
$shift['URL'],
|
||||
$user->id,
|
||||
time(),
|
||||
$shift['SID']
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param int $transactionId
|
||||
* @return int|false ID of the new created shift
|
||||
*/
|
||||
function Shift_create($shift, $transactionId = null)
|
||||
{
|
||||
Db::insert(
|
||||
'
|
||||
INSERT INTO `Shifts` (
|
||||
`shifttype_id`,
|
||||
`start`,
|
||||
`end`,
|
||||
`RID`,
|
||||
`title`,
|
||||
`description`,
|
||||
`URL`,
|
||||
`transaction_id`,
|
||||
`created_by_user_id`,
|
||||
`edited_at_timestamp`,
|
||||
`created_at_timestamp`
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
',
|
||||
[
|
||||
$shift['shifttype_id'],
|
||||
$shift['start'],
|
||||
$shift['end'],
|
||||
$shift['RID'],
|
||||
$shift['title'],
|
||||
$shift['description'],
|
||||
$shift['URL'],
|
||||
$transactionId,
|
||||
auth()->user()->id,
|
||||
time(),
|
||||
time(),
|
||||
]
|
||||
);
|
||||
|
||||
return Db::getPdo()->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return users shifts.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param bool $include_freeload_comments
|
||||
* @return array[]
|
||||
* @return Collection|Shift[]
|
||||
*/
|
||||
function Shifts_by_user($userId, $include_freeload_comments = false)
|
||||
{
|
||||
return Db::select(
|
||||
$shiftsData = Db::select(
|
||||
'
|
||||
SELECT
|
||||
`rooms`.*,
|
||||
`rooms`.name AS Name,
|
||||
`shift_types`.`id` AS `shifttype_id`,
|
||||
`shift_types`.`name`,
|
||||
`ShiftEntry`.`id`,
|
||||
`ShiftEntry`.`id` as shift_entry_id,
|
||||
`ShiftEntry`.`SID`,
|
||||
`ShiftEntry`.`TID`,
|
||||
`ShiftEntry`.`UID`,
|
||||
`ShiftEntry`.`freeloaded`,
|
||||
`ShiftEntry`.`Comment`,
|
||||
' . ($include_freeload_comments ? '`ShiftEntry`.`freeload_comment`, ' : '') . '
|
||||
`Shifts`.*,
|
||||
@@session.time_zone AS timezone,
|
||||
? AS event_timezone
|
||||
`shifts`.*
|
||||
FROM `ShiftEntry`
|
||||
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
|
||||
JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
|
||||
JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`)
|
||||
WHERE `UID` = ?
|
||||
JOIN `shifts` ON (`ShiftEntry`.`SID` = `shifts`.`id`)
|
||||
JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`)
|
||||
JOIN `rooms` ON (`shifts`.`room_id` = `rooms`.`id`)
|
||||
WHERE ShiftEntry.`UID` = ?
|
||||
ORDER BY `start`
|
||||
',
|
||||
[
|
||||
config('timezone'),
|
||||
$userId,
|
||||
]
|
||||
);
|
||||
|
||||
$shifts = [];
|
||||
foreach ($shiftsData as $data) {
|
||||
$shifts[] = (new Shift())->forceFill($data);
|
||||
}
|
||||
|
||||
return collect($shifts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Shift by id.
|
||||
* Returns Shift by id or extends existing Shift
|
||||
*
|
||||
* @param int $shift_id Shift ID
|
||||
* @return array|null
|
||||
* @param int|Shift $shift Shift ID or shift model
|
||||
* @return Shift|null
|
||||
*/
|
||||
function Shift($shift_id)
|
||||
function Shift($shift)
|
||||
{
|
||||
$result = Db::selectOne('
|
||||
SELECT `Shifts`.*, `shift_types`.`name`
|
||||
FROM `Shifts`
|
||||
JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
|
||||
WHERE `SID`=?', [$shift_id]);
|
||||
if (!$shift instanceof Shift) {
|
||||
$shift = Shift::find($shift);
|
||||
}
|
||||
|
||||
if (empty($result)) {
|
||||
if (!$shift) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$shiftsEntry_source = Db::select('
|
||||
$shift->shiftEntry = Db::select('
|
||||
SELECT
|
||||
`ShiftEntry`.`id`, `ShiftEntry`.`TID` , `ShiftEntry`.`UID` , `ShiftEntry`.`freeloaded`,
|
||||
`users`.`name` AS `username`, `users`.`id` AS `user_id`
|
||||
FROM `ShiftEntry`
|
||||
LEFT JOIN `users` ON (`users`.`id` = `ShiftEntry`.`UID`)
|
||||
WHERE `SID`=?', [$shift_id]);
|
||||
WHERE `SID`=?', [$shift->id]);
|
||||
|
||||
$result['ShiftEntry'] = $shiftsEntry_source;
|
||||
$result['NeedAngels'] = [];
|
||||
|
||||
$angelTypes = NeededAngelTypes_by_shift($shift_id);
|
||||
$neededAngels = [];
|
||||
$angelTypes = NeededAngelTypes_by_shift($shift->id);
|
||||
foreach ($angelTypes as $type) {
|
||||
$result['NeedAngels'][] = [
|
||||
$neededAngels[] = [
|
||||
'TID' => $type['angel_type_id'],
|
||||
'count' => $type['count'],
|
||||
'restricted' => $type['restricted'],
|
||||
'taken' => $type['taken']
|
||||
];
|
||||
}
|
||||
$shift->neededAngels = $neededAngels;
|
||||
|
||||
return $result;
|
||||
return $shift;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ function stats_currently_working(ShiftsFilter $filter = null)
|
|||
SELECT SUM((
|
||||
SELECT COUNT(*)
|
||||
FROM `ShiftEntry`
|
||||
WHERE `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
WHERE `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
AND `freeloaded`=0
|
||||
' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
)) AS `count`
|
||||
FROM `Shifts`
|
||||
WHERE (`end` >= UNIX_TIMESTAMP() AND `start` <= UNIX_TIMESTAMP())
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '')
|
||||
FROM `shifts`
|
||||
WHERE (`end` >= NOW() AND `start` <= NOW())
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '')
|
||||
);
|
||||
|
||||
return $result['count'] ?: '-';
|
||||
|
@ -42,24 +42,24 @@ function stats_hours_to_work(ShiftsFilter $filter = null)
|
|||
'
|
||||
SELECT ROUND(SUM(`count`)) AS `count` FROM (
|
||||
SELECT
|
||||
(SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
* (`Shifts`.`end` - `Shifts`.`start`)/3600 AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `end` >= UNIX_TIMESTAMP()
|
||||
(SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
* TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count`
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `shifts`.`end` >= NOW()
|
||||
AND s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
(SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
* (`Shifts`.`end` - `Shifts`.`start`)/3600 AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `end` >= UNIX_TIMESTAMP()
|
||||
(SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
|
||||
* TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count`
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE shifts.`end` >= NOW()
|
||||
AND NOT s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
) AS `tmp`
|
||||
'
|
||||
);
|
||||
|
@ -86,23 +86,23 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
|
|||
FROM `NeededAngelTypes`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||
AND `NeededAngelTypes`.`shift_id`=`shifts`.`id`
|
||||
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
) - (
|
||||
SELECT COUNT(*) FROM `ShiftEntry`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`ShiftEntry`.`TID`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
AND `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
AND `freeloaded`=0
|
||||
' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
)
|
||||
)
|
||||
AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `end` > UNIX_TIMESTAMP() AND `start` < ?
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE shifts.`end` > NOW() AND shifts.`start` < ?
|
||||
AND s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
|
||||
UNION ALL
|
||||
|
||||
|
@ -113,23 +113,23 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
|
|||
FROM `NeededAngelTypes`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
|
||||
AND `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
|
||||
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
) - (
|
||||
SELECT COUNT(*) FROM `ShiftEntry`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`ShiftEntry`.`TID`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
AND `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
AND `freeloaded`=0
|
||||
' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
)
|
||||
)
|
||||
AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `end` > UNIX_TIMESTAMP() AND `start` < ?
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `end` > NOW() AND `start` < ?
|
||||
AND NOT s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
) AS `tmp`', [
|
||||
$in3hours,
|
||||
$in3hours
|
||||
|
@ -165,23 +165,23 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
|
|||
FROM `NeededAngelTypes`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||
AND `NeededAngelTypes`.`shift_id`=`shifts`.`id`
|
||||
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
) - (
|
||||
SELECT COUNT(*) FROM `ShiftEntry`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`ShiftEntry`.`TID`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
AND `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
AND `freeloaded`=0
|
||||
' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
)
|
||||
)
|
||||
AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
WHERE `end` > ? AND `start` < ?
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE shifts.`end` > ? AND shifts.`start` < ?
|
||||
AND s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
|
||||
UNION ALL
|
||||
|
||||
|
@ -192,23 +192,23 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
|
|||
FROM `NeededAngelTypes`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
|
||||
AND `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
|
||||
' . ($filter ? 'AND angel_types.id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
) - (
|
||||
SELECT COUNT(*) FROM `ShiftEntry`
|
||||
JOIN `angel_types` ON `angel_types`.`id`=`ShiftEntry`.`TID`
|
||||
WHERE `angel_types`.`show_on_dashboard`=TRUE
|
||||
AND `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||
AND `ShiftEntry`.`SID`=`shifts`.`id`
|
||||
AND `freeloaded`=0
|
||||
' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
|
||||
)
|
||||
)
|
||||
AS `count`
|
||||
FROM `Shifts`
|
||||
LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id
|
||||
FROM `shifts`
|
||||
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
|
||||
WHERE `end` > ? AND `start` < ?
|
||||
AND NOT s.shift_id IS NULL
|
||||
' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
|
||||
) AS `tmp`', [
|
||||
$night_start,
|
||||
$night_end,
|
||||
|
|
|
@ -26,13 +26,12 @@ function User_tshirt_score($userId)
|
|||
$result_shifts = Db::selectOne(sprintf('
|
||||
SELECT ROUND((%s) / 3600, 2) AS `tshirt_score`
|
||||
FROM `users` LEFT JOIN `ShiftEntry` ON `users`.`id` = `ShiftEntry`.`UID`
|
||||
LEFT JOIN `Shifts` ON `ShiftEntry`.`SID` = `Shifts`.`SID`
|
||||
LEFT JOIN `shifts` ON `ShiftEntry`.`SID` = `shifts`.`id`
|
||||
WHERE `users`.`id` = ?
|
||||
AND `Shifts`.`end` < ?
|
||||
AND `shifts`.`end` < NOW()
|
||||
GROUP BY `users`.`id`
|
||||
', $shift_sum_formula), [
|
||||
$userId,
|
||||
time()
|
||||
$userId
|
||||
]);
|
||||
if (!isset($result_shifts['tshirt_score'])) {
|
||||
$result_shifts = ['tshirt_score' => 0];
|
||||
|
@ -197,7 +196,7 @@ function User_get_eligable_voucher_count($user)
|
|||
? Carbon::createFromFormat('Y-m-d', $voucher_settings['voucher_start'])->setTime(0, 0)
|
||||
: null;
|
||||
|
||||
$shifts = ShiftEntries_finished_by_user($user->id, $start);
|
||||
$shifts = ShiftEntries_finished_by_user($user, $start);
|
||||
$worklog = UserWorkLogsForUser($user->id, $start);
|
||||
$shifts_done =
|
||||
count($shifts)
|
||||
|
@ -205,7 +204,7 @@ function User_get_eligable_voucher_count($user)
|
|||
|
||||
$shiftsTime = 0;
|
||||
foreach ($shifts as $shift) {
|
||||
$shiftsTime += ($shift['end'] - $shift['start']) / 60 / 60;
|
||||
$shiftsTime += (Carbon::make($shift['end'])->timestamp - Carbon::make($shift['start'])->timestamp) / 60 / 60;
|
||||
}
|
||||
foreach ($worklog as $entry) {
|
||||
$shiftsTime += $entry->hours;
|
||||
|
@ -237,18 +236,18 @@ function User_get_shifts_sum_query()
|
|||
{
|
||||
$nightShifts = config('night_shifts');
|
||||
if (!$nightShifts['enabled']) {
|
||||
return 'COALESCE(SUM(`end` - `start`), 0)';
|
||||
return 'COALESCE(SUM(UNIX_TIMESTAMP(shifts.end) - UNIX_TIMESTAMP(shifts.start)), 0)';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'
|
||||
COALESCE(SUM(
|
||||
(1 + (
|
||||
(HOUR(FROM_UNIXTIME(`Shifts`.`end`)) > %1$d AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) < %2$d)
|
||||
OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) > %1$d AND HOUR(FROM_UNIXTIME(`Shifts`.`start`)) < %2$d)
|
||||
OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) <= %1$d AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) >= %2$d)
|
||||
(HOUR(shifts.end) > %1$d AND HOUR(shifts.end) < %2$d)
|
||||
OR (HOUR(shifts.start) > %1$d AND HOUR(shifts.start) < %2$d)
|
||||
OR (HOUR(shifts.start) <= %1$d AND HOUR(shifts.end) >= %2$d)
|
||||
))
|
||||
* (`Shifts`.`end` - `Shifts`.`start`)
|
||||
* (UNIX_TIMESTAMP(shifts.end) - UNIX_TIMESTAMP(shifts.start))
|
||||
* (1 - (%3$d + 1) * `ShiftEntry`.`freeloaded`)
|
||||
), 0)
|
||||
',
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\User\State;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
@ -70,7 +71,7 @@ function admin_active()
|
|||
)
|
||||
)
|
||||
->leftJoin('ShiftEntry', 'users.id', '=', 'ShiftEntry.UID')
|
||||
->leftJoin('Shifts', 'ShiftEntry.SID', '=', 'Shifts.SID')
|
||||
->leftJoin('shifts', 'ShiftEntry.SID', '=', 'shifts.id')
|
||||
->leftJoin('users_state', 'users.id', '=', 'users_state.user_id')
|
||||
->where('users_state.arrived', '=', true)
|
||||
->groupBy('users.id')
|
||||
|
@ -162,14 +163,14 @@ function admin_active()
|
|||
)
|
||||
)
|
||||
->leftJoin('ShiftEntry', 'users.id', '=', 'ShiftEntry.UID')
|
||||
->leftJoin('Shifts', function ($join) use ($show_all_shifts) {
|
||||
->leftJoin('shifts', function ($join) use ($show_all_shifts) {
|
||||
/** @var JoinClause $join */
|
||||
$join->on('ShiftEntry.SID', '=', 'Shifts.SID');
|
||||
$join->on('ShiftEntry.SID', '=', 'shifts.id');
|
||||
if (!$show_all_shifts) {
|
||||
$join->where(function ($query) {
|
||||
/** @var Builder $query */
|
||||
$query->where('Shifts.end', '<', time())
|
||||
->orWhereNull('Shifts.end');
|
||||
$query->where('shifts.end', '<', Carbon::now())
|
||||
->orWhereNull('shifts.end');
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
|
@ -41,14 +42,14 @@ function admin_free()
|
|||
->select('users.*')
|
||||
->leftJoin('ShiftEntry', 'users.id', 'ShiftEntry.UID')
|
||||
->leftJoin('users_state', 'users.id', 'users_state.user_id')
|
||||
->leftJoin('Shifts', function ($join) {
|
||||
->leftJoin('shifts', function ($join) {
|
||||
/** @var JoinClause $join */
|
||||
$join->on('ShiftEntry.SID', '=', 'Shifts.SID')
|
||||
->where('Shifts.start', '<', time())
|
||||
->where('Shifts.end', '>', time());
|
||||
$join->on('ShiftEntry.SID', '=', 'shifts.id')
|
||||
->where('shifts.start', '<', Carbon::now())
|
||||
->where('shifts.end', '>', Carbon::now());
|
||||
})
|
||||
->where('users_state.arrived', '=', 1)
|
||||
->whereNull('Shifts.SID')
|
||||
->whereNull('shifts.id')
|
||||
->orderBy('users.name')
|
||||
->groupBy('users.id');
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
@ -187,17 +186,17 @@ function admin_rooms()
|
|||
} elseif ($request->input('show') == 'delete') {
|
||||
if ($request->hasPostData('ack')) {
|
||||
$room = Room::find($room_id);
|
||||
$shifts = Shifts_by_room($room);
|
||||
$shifts = $room->shifts;
|
||||
foreach ($shifts as $shift) {
|
||||
$shift = Shift($shift['SID']);
|
||||
foreach ($shift['ShiftEntry'] as $entry) {
|
||||
$shift = Shift($shift);
|
||||
foreach ($shift->shiftEntry as $entry) {
|
||||
$type = AngelType::find($entry['TID']);
|
||||
event('shift.entry.deleting', [
|
||||
'user' => User::find($entry['user_id']),
|
||||
'start' => Carbon::createFromTimestamp($shift['start']),
|
||||
'end' => Carbon::createFromTimestamp($shift['end']),
|
||||
'name' => $shift['name'],
|
||||
'title' => $shift['title'],
|
||||
'start' => $shift->start,
|
||||
'end' => $shift->end,
|
||||
'name' => $shift->shiftType->name,
|
||||
'title' => $shift->title,
|
||||
'type' => $type->name,
|
||||
'room' => $room,
|
||||
'freeloaded' => (bool) $entry['freeloaded'],
|
||||
|
|
|
@ -5,6 +5,7 @@ use Engelsystem\Helpers\Carbon;
|
|||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Support\Str;
|
||||
|
@ -27,7 +28,7 @@ function admin_shifts()
|
|||
$valid = true;
|
||||
$request = request();
|
||||
$session = session();
|
||||
$start = Carbon::createTimestampFromDatetime(date('Y-m-d') . 'T00:00');
|
||||
$start = Carbon::createFromDateTime(date('Y-m-d') . 'T00:00');
|
||||
$end = $start;
|
||||
$mode = 'multi';
|
||||
$angelmode = 'manually';
|
||||
|
@ -46,7 +47,7 @@ function admin_shifts()
|
|||
$room_array[$room->id] = $room->name;
|
||||
}
|
||||
|
||||
// Engeltypen laden
|
||||
// Load angeltypes
|
||||
$types = AngelType::all();
|
||||
$needed_angel_types = [];
|
||||
foreach ($types as $type) {
|
||||
|
@ -93,14 +94,14 @@ function admin_shifts()
|
|||
error(__('Please select a location.'));
|
||||
}
|
||||
|
||||
if ($request->has('start') && $tmp = Carbon::createTimestampFromDatetime($request->input('start'))) {
|
||||
if ($request->has('start') && $tmp = Carbon::createFromDateTime($request->input('start'))) {
|
||||
$start = $tmp;
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please select a start time.'));
|
||||
}
|
||||
|
||||
if ($request->has('end') && $tmp = Carbon::createTimestampFromDatetime($request->input('end'))) {
|
||||
if ($request->has('end') && $tmp = Carbon::createFromDateTime($request->input('end'))) {
|
||||
$end = $tmp;
|
||||
} else {
|
||||
$valid = false;
|
||||
|
@ -201,15 +202,15 @@ function admin_shifts()
|
|||
$shifts[] = [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'RID' => $rid,
|
||||
'room_id' => $rid,
|
||||
'title' => $title,
|
||||
'shifttype_id' => $shifttype_id,
|
||||
'shift_type_id' => $shifttype_id,
|
||||
'description' => $description,
|
||||
];
|
||||
} elseif ($mode == 'multi') {
|
||||
$shift_start = (int) $start;
|
||||
$shift_start = $start;
|
||||
do {
|
||||
$shift_end = $shift_start + (int) $length * 60;
|
||||
$shift_end = (clone $shift_start)->addSeconds((int) $length * 60);
|
||||
|
||||
if ($shift_end > $end) {
|
||||
$shift_end = $end;
|
||||
|
@ -221,9 +222,9 @@ function admin_shifts()
|
|||
$shifts[] = [
|
||||
'start' => $shift_start,
|
||||
'end' => $shift_end,
|
||||
'RID' => $rid,
|
||||
'room_id' => $rid,
|
||||
'title' => $title,
|
||||
'shifttype_id' => $shifttype_id,
|
||||
'shift_type_id' => $shifttype_id,
|
||||
'description' => $description,
|
||||
];
|
||||
|
||||
|
@ -238,8 +239,8 @@ function admin_shifts()
|
|||
});
|
||||
|
||||
// Alle Tage durchgehen
|
||||
$end_day = Carbon::createTimestampFromDatetime(date('Y-m-d', $end) . ' 00:00');
|
||||
$day = Carbon::createTimestampFromDatetime(date('Y-m-d', $start) . ' 00:00');
|
||||
$end_day = Carbon::createFromDatetime($end->format('Y-m-d') . ' 00:00');
|
||||
$day = Carbon::createFromDatetime($start->format('Y-m-d') . ' 00:00');
|
||||
do {
|
||||
// Alle Schichtwechselstunden durchgehen
|
||||
for ($i = 0; $i < count($change_hours); $i++) {
|
||||
|
@ -248,20 +249,21 @@ function admin_shifts()
|
|||
// Normales Intervall zwischen zwei Schichtwechselstunden
|
||||
$end_hour = $change_hours[$i + 1];
|
||||
} elseif ($shift_over_midnight) {
|
||||
// Letzte Schichtwechselstunde: Wenn eine 24h Abdeckung gewünscht ist, hier die erste Schichtwechselstunde als Ende ensetzen
|
||||
// Letzte Schichtwechselstunde: Wenn eine 24h Abdeckung gewünscht ist,
|
||||
// hier die erste Schichtwechselstunde als Ende einsetzen
|
||||
$end_hour = $change_hours[0];
|
||||
} else {
|
||||
// Letzte Schichtwechselstunde: Keine Schicht erstellen
|
||||
break;
|
||||
}
|
||||
|
||||
$interval_start = Carbon::createTimestampFromDatetime(date('Y-m-d', $day) . ' ' . $start_hour);
|
||||
$interval_start = Carbon::createFromDatetime($day->format('Y-m-d') . ' ' . $start_hour);
|
||||
if (str_replace(':', '', $end_hour) < str_replace(':', '', $start_hour)) {
|
||||
// Endstunde kleiner Startstunde? Dann sind wir im nächsten Tag gelandet
|
||||
$interval_end = Carbon::createTimestampFromDatetime(date('Y-m-d', $day + 36 * 60 * 60) . ' ' . $end_hour);
|
||||
$interval_end = Carbon::createFromDatetime(date('Y-m-d', $day->timestamp + 36 * 60 * 60) . ' ' . $end_hour);
|
||||
} else {
|
||||
// Endstunde ist noch im selben Tag
|
||||
$interval_end = Carbon::createTimestampFromDatetime(date('Y-m-d', $day) . ' ' . $end_hour);
|
||||
$interval_end = Carbon::createFromDatetime($day->format('Y-m-d', $day) . ' ' . $end_hour);
|
||||
}
|
||||
|
||||
// Liegt das Intervall vor dem Startzeitpunkt -> Überspringen
|
||||
|
@ -288,14 +290,14 @@ function admin_shifts()
|
|||
$shifts[] = [
|
||||
'start' => $interval_start,
|
||||
'end' => $interval_end,
|
||||
'RID' => $rid,
|
||||
'room_id' => $rid,
|
||||
'title' => $title,
|
||||
'shifttype_id' => $shifttype_id,
|
||||
'shift_type_id' => $shifttype_id,
|
||||
'description' => $description
|
||||
];
|
||||
}
|
||||
|
||||
$day = Carbon::createTimestampFromDatetime(date('Y-m-d', $day + 36 * 60 * 60) . ' 00:00');
|
||||
$day = Carbon::createFromDatetime(date('Y-m-d', $day->timestamp + 36 * 60 * 60) . ' 00:00');
|
||||
} while ($day <= $end_day);
|
||||
|
||||
usort($shifts, function ($a, $b) {
|
||||
|
@ -308,11 +310,11 @@ function admin_shifts()
|
|||
$shifts_table_entry = [
|
||||
'timeslot' =>
|
||||
icon('clock-history') . ' '
|
||||
. date('Y-m-d H:i', $shift['start'])
|
||||
. $shift['start']->format('Y-m-d H:i')
|
||||
. ' - '
|
||||
. date('H:i', $shift['end'])
|
||||
. $shift['end']->format('H:i')
|
||||
. '<br />'
|
||||
. Room_name_render(Room::find($shift['RID'])),
|
||||
. Room_name_render(Room::find($shift['room_id'])),
|
||||
'title' =>
|
||||
ShiftType_name_render(ShiftType::find($shifttype_id))
|
||||
. ($shift['title'] ? '<br />' . $shift['title'] : ''),
|
||||
|
@ -342,8 +344,8 @@ function admin_shifts()
|
|||
form_hidden('description', $description),
|
||||
form_hidden('title', $title),
|
||||
form_hidden('rid', $rid),
|
||||
form_hidden('start', date('Y-m-d H:i', $start)),
|
||||
form_hidden('end', date('Y-m-d H:i', $end)),
|
||||
form_hidden('start', $start->format('Y-m-d H:i')),
|
||||
form_hidden('end', $end->format('Y-m-d H:i')),
|
||||
form_hidden('mode', $mode),
|
||||
form_hidden('length', $length),
|
||||
form_hidden('change_hours', implode(', ', $change_hours)),
|
||||
|
@ -369,15 +371,19 @@ function admin_shifts()
|
|||
|
||||
$transactionId = Str::uuid();
|
||||
foreach ($session->get('admin_shifts_shifts', []) as $shift) {
|
||||
$shift['URL'] = null;
|
||||
$shift_id = Shift_create($shift, $transactionId);
|
||||
$shift = new Shift($shift);
|
||||
$shift->url = '';
|
||||
$shift->transaction_id = $transactionId;
|
||||
$shift->createdBy()->associate(auth()->user());
|
||||
$shift->save();
|
||||
$shift_id = $shift->id;
|
||||
|
||||
engelsystem_log(
|
||||
'Shift created: ' . $shifttypes[$shift['shifttype_id']]
|
||||
. ' with title ' . $shift['title']
|
||||
. ' with description ' . $shift['description']
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
'Shift created: ' . $shifttypes[$shift->shift_type_id]
|
||||
. ' with title ' . $shift->title
|
||||
. ' with description ' . $shift->description
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
. ', transaction: ' . $transactionId
|
||||
);
|
||||
|
||||
|
@ -405,7 +411,7 @@ function admin_shifts()
|
|||
engelsystem_log('Shift needs following angel types: ' . join(', ', $needed_angel_types_info));
|
||||
}
|
||||
|
||||
success('Schichten angelegt.');
|
||||
success('Shifts created.');
|
||||
throw_redirect(page_link_to('admin_shifts'));
|
||||
} else {
|
||||
$session->remove('admin_shifts_shifts');
|
||||
|
@ -550,37 +556,32 @@ function admin_shifts_history(): string
|
|||
$request = request();
|
||||
$transactionId = $request->postData('transaction_id');
|
||||
if ($request->hasPostData('delete') && $transactionId) {
|
||||
$shifts = Db::select('
|
||||
SELECT SID
|
||||
FROM Shifts
|
||||
WHERE transaction_id = ?
|
||||
', [$transactionId]);
|
||||
$shifts = Shift::whereTransactionId($transactionId);
|
||||
|
||||
engelsystem_log('Deleting ' . count($shifts) . ' shifts (transaction id ' . $transactionId . ')');
|
||||
|
||||
foreach ($shifts as $shift) {
|
||||
$shift = Shift($shift['SID']);
|
||||
$room = Room::find($shift['RID']);
|
||||
foreach ($shift['ShiftEntry'] as $entry) {
|
||||
$shift = Shift($shift);
|
||||
foreach ($shift->shiftEntry as $entry) {
|
||||
$type = AngelType::find($entry['TID']);
|
||||
event('shift.entry.deleting', [
|
||||
'user' => User::find($entry['user_id']),
|
||||
'start' => Carbon::createFromTimestamp($shift['start']),
|
||||
'end' => Carbon::createFromTimestamp($shift['end']),
|
||||
'name' => $shift['name'],
|
||||
'title' => $shift['title'],
|
||||
'start' => $shift->start,
|
||||
'end' => $shift->end,
|
||||
'name' => $shift->shiftType->name,
|
||||
'title' => $shift->title,
|
||||
'type' => $type->name,
|
||||
'room' => $room,
|
||||
'room' => $shift->room,
|
||||
'freeloaded' => (bool) $entry['freeloaded'],
|
||||
]);
|
||||
}
|
||||
|
||||
shift_delete($shift['SID']);
|
||||
$shift->delete();
|
||||
|
||||
engelsystem_log(
|
||||
'Deleted shift ' . $shift['name']
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
'Deleted shift ' . $shift->title . ' / ' . $shift->shiftType->name
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -588,28 +589,28 @@ function admin_shifts_history(): string
|
|||
throw_redirect(page_link_to('admin_shifts_history'));
|
||||
}
|
||||
|
||||
$shifts = Db::select('
|
||||
$shiftsData = Db::select('
|
||||
SELECT
|
||||
transaction_id,
|
||||
title,
|
||||
COUNT(SID) AS count,
|
||||
COUNT(id) AS count,
|
||||
MIN(start) AS start,
|
||||
MAX(end) AS end,
|
||||
created_by_user_id AS user_id,
|
||||
created_at_timestamp AS created_at
|
||||
FROM Shifts
|
||||
created_by AS user_id,
|
||||
MAX(created_at) AS created_at
|
||||
FROM shifts
|
||||
WHERE transaction_id IS NOT NULL
|
||||
GROUP BY transaction_id
|
||||
ORDER BY transaction_id DESC
|
||||
ORDER BY created_at DESC
|
||||
');
|
||||
|
||||
foreach ($shifts as &$shift) {
|
||||
$shift['user'] = User_Nick_render(User::find($shift['user_id']));
|
||||
$shift['start'] = Carbon::createFromTimestamp($shift['start'])->format(__('Y-m-d H:i'));
|
||||
$shift['end'] = Carbon::createFromTimestamp($shift['end'])->format(__('Y-m-d H:i'));
|
||||
$shift['created_at'] = Carbon::createFromTimestamp($shift['created_at'])->format(__('Y-m-d H:i'));
|
||||
$shift['actions'] = form([
|
||||
form_hidden('transaction_id', $shift['transaction_id']),
|
||||
foreach ($shiftsData as &$shiftData) {
|
||||
$shiftData['user'] = User_Nick_render(User::find($shiftData['user_id']));
|
||||
$shiftData['start'] = Carbon::make($shiftData['start'])->format(__('Y-m-d H:i'));
|
||||
$shiftData['end'] = Carbon::make($shiftData['end'])->format(__('Y-m-d H:i'));
|
||||
$shiftData['created_at'] = Carbon::make($shiftData['created_at'])->format(__('Y-m-d H:i'));
|
||||
$shiftData['actions'] = form([
|
||||
form_hidden('transaction_id', $shiftData['transaction_id']),
|
||||
form_submit('delete', icon('trash') . __('delete all'), 'btn-sm', true, 'danger'),
|
||||
]);
|
||||
}
|
||||
|
@ -625,6 +626,6 @@ function admin_shifts_history(): string
|
|||
'user' => __('User'),
|
||||
'created_at' => __('Created'),
|
||||
'actions' => ''
|
||||
], $shifts)
|
||||
], $shiftsData)
|
||||
], true);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use Engelsystem\Http\Response;
|
|||
use Engelsystem\Models\Room as RoomModel;
|
||||
use Engelsystem\Models\Shifts\Schedule as ScheduleUrl;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use ErrorException;
|
||||
|
@ -27,7 +28,6 @@ use Illuminate\Database\Eloquent\Builder as QueryBuilder;
|
|||
use Illuminate\Database\Eloquent\Collection as DatabaseCollection;
|
||||
use Illuminate\Support\Collection;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use stdClass;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
class ImportSchedule extends BaseController
|
||||
|
@ -267,22 +267,22 @@ class ImportSchedule extends BaseController
|
|||
$shiftEntries = $this->db
|
||||
->table('ShiftEntry')
|
||||
->select([
|
||||
'shift_types.name', 'Shifts.title', 'angel_types.name AS type', 'rooms.id AS room_id',
|
||||
'Shifts.start', 'Shifts.end', 'ShiftEntry.UID as user_id', 'ShiftEntry.freeloaded'
|
||||
'shift_types.name', 'shifts.title', 'angel_types.name AS type', 'rooms.id AS room_id',
|
||||
'shifts.start', 'shifts.end', 'ShiftEntry.UID as user_id', 'ShiftEntry.freeloaded'
|
||||
])
|
||||
->join('Shifts', 'Shifts.SID', 'ShiftEntry.SID')
|
||||
->join('schedule_shift', 'Shifts.SID', 'schedule_shift.shift_id')
|
||||
->join('rooms', 'rooms.id', 'Shifts.RID')
|
||||
->join('shifts', 'shifts.id', 'ShiftEntry.SID')
|
||||
->join('schedule_shift', 'shifts.id', 'schedule_shift.shift_id')
|
||||
->join('rooms', 'rooms.id', 'shifts.room_id')
|
||||
->join('angel_types', 'angel_types.id', 'ShiftEntry.TID')
|
||||
->join('shift_types', 'shift_types.id', 'Shifts.shifttype_id')
|
||||
->join('shift_types', 'shift_types.id', 'shifts.shift_type_id')
|
||||
->where('schedule_shift.guid', $event->getGuid())
|
||||
->get();
|
||||
|
||||
foreach ($shiftEntries as $shiftEntry) {
|
||||
event('shift.entry.deleting', [
|
||||
'user' => User::find($shiftEntry->user_id),
|
||||
'start' => Carbon::createFromTimestamp($shiftEntry->start),
|
||||
'end' => Carbon::createFromTimestamp($shiftEntry->end),
|
||||
'start' => Carbon::make($shiftEntry->start),
|
||||
'end' => Carbon::make($shiftEntry->end),
|
||||
'name' => $shiftEntry->name,
|
||||
'title' => $shiftEntry->title,
|
||||
'type' => $shiftEntry->type,
|
||||
|
@ -292,93 +292,82 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
protected function createEvent(Event $shift, int $shiftTypeId, RoomModel $room, ScheduleUrl $scheduleUrl): void
|
||||
protected function createEvent(Event $event, int $shiftTypeId, RoomModel $room, ScheduleUrl $scheduleUrl): void
|
||||
{
|
||||
$user = auth()->user();
|
||||
$eventTimeZone = Carbon::now()->timezone;
|
||||
|
||||
$this->db
|
||||
->table('Shifts')
|
||||
->insert(
|
||||
[
|
||||
'title' => $shift->getTitle(),
|
||||
'shifttype_id' => $shiftTypeId,
|
||||
'start' => $shift->getDate()->unix(),
|
||||
'end' => $shift->getEndDate()->unix(),
|
||||
'RID' => $room->id,
|
||||
'URL' => $shift->getUrl(),
|
||||
'created_by_user_id' => $user->id,
|
||||
'created_at_timestamp' => time(),
|
||||
'edited_by_user_id' => null,
|
||||
'edited_at_timestamp' => 0,
|
||||
]
|
||||
);
|
||||
$shift = new Shift();
|
||||
$shift->title = $event->getTitle();
|
||||
$shift->shift_type_id = $shiftTypeId;
|
||||
$shift->start = $event->getDate()->copy()->timezone($eventTimeZone);
|
||||
$shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone);
|
||||
$shift->room()->associate($room);
|
||||
$shift->url = $event->getUrl() ?? '';
|
||||
$shift->createdBy()->associate($user);
|
||||
$shift->save();
|
||||
|
||||
$shiftId = $this->db->getDoctrineConnection()->lastInsertId();
|
||||
|
||||
$scheduleShift = new ScheduleShift(['shift_id' => $shiftId, 'guid' => $shift->getGuid()]);
|
||||
$scheduleShift = new ScheduleShift(['guid' => $event->getGuid()]);
|
||||
$scheduleShift->schedule()->associate($scheduleUrl);
|
||||
$scheduleShift->shift()->associate($shift);
|
||||
$scheduleShift->save();
|
||||
|
||||
$this->log(
|
||||
'Created schedule shift "{shift}" in "{room}" ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->getTitle(),
|
||||
'room' => $room->name,
|
||||
'from' => $shift->getDate()->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->getEndDate()->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $shift->getGuid(),
|
||||
'shift' => $shift->title,
|
||||
'room' => $shift->room->name,
|
||||
'from' => $shift->start->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->end->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $scheduleShift->guid,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function updateEvent(Event $shift, int $shiftTypeId, RoomModel $room): void
|
||||
protected function updateEvent(Event $event, int $shiftTypeId, RoomModel $room): void
|
||||
{
|
||||
$user = auth()->user();
|
||||
$eventTimeZone = Carbon::now()->timezone;
|
||||
|
||||
$this->db
|
||||
->table('Shifts')
|
||||
->join('schedule_shift', 'Shifts.SID', 'schedule_shift.shift_id')
|
||||
->where('schedule_shift.guid', $shift->getGuid())
|
||||
->update(
|
||||
[
|
||||
'title' => $shift->getTitle(),
|
||||
'shifttype_id' => $shiftTypeId,
|
||||
'start' => $shift->getDate()->unix(),
|
||||
'end' => $shift->getEndDate()->unix(),
|
||||
'RID' => $room->id,
|
||||
'URL' => $shift->getUrl(),
|
||||
'edited_by_user_id' => $user->id,
|
||||
'edited_at_timestamp' => time(),
|
||||
]
|
||||
);
|
||||
/** @var ScheduleShift $scheduleShift */
|
||||
$scheduleShift = ScheduleShift::whereGuid($event->getGuid())->first();
|
||||
$shift = $scheduleShift->shift;
|
||||
$shift->title = $event->getTitle();
|
||||
$shift->shift_type_id = $shiftTypeId;
|
||||
$shift->start = $event->getDate()->copy()->timezone($eventTimeZone);
|
||||
$shift->end = $event->getEndDate()->copy()->timezone($eventTimeZone);
|
||||
$shift->room()->associate($room);
|
||||
$shift->url = $event->getUrl() ?? '';
|
||||
$shift->updatedBy()->associate($user);
|
||||
$shift->save();
|
||||
|
||||
$this->log(
|
||||
'Updated schedule shift "{shift}" in "{room}" ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->getTitle(),
|
||||
'room' => $room->name,
|
||||
'from' => $shift->getDate()->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->getEndDate()->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $shift->getGuid(),
|
||||
'shift' => $shift->title,
|
||||
'room' => $shift->room->name,
|
||||
'from' => $shift->start->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->end->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $scheduleShift->guid,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function deleteEvent(Event $shift): void
|
||||
protected function deleteEvent(Event $event): void
|
||||
{
|
||||
$this->db
|
||||
->table('Shifts')
|
||||
->join('schedule_shift', 'Shifts.SID', 'schedule_shift.shift_id')
|
||||
->where('schedule_shift.guid', $shift->getGuid())
|
||||
->delete();
|
||||
/** @var ScheduleShift $scheduleShift */
|
||||
$scheduleShift = ScheduleShift::whereGuid($event->getGuid())->first();
|
||||
$shift = $scheduleShift->shift;
|
||||
$shift->delete();
|
||||
|
||||
$this->log(
|
||||
'Deleted schedule shift "{shift}" ({from} {to}, {guid})',
|
||||
'Deleted schedule shift "{shift}" in {room} ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->getTitle(),
|
||||
'from' => $shift->getDate()->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->getEndDate()->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $shift->getGuid(),
|
||||
'shift' => $shift->title,
|
||||
'room' => $shift->room->name,
|
||||
'from' => $shift->start->format(DateTimeInterface::RFC3339),
|
||||
'to' => $shift->end->format(DateTimeInterface::RFC3339),
|
||||
'guid' => $scheduleShift->guid,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -465,15 +454,20 @@ class ImportSchedule extends BaseController
|
|||
/** @var Event[] $deleteEvents */
|
||||
$deleteEvents = [];
|
||||
$rooms = $this->getAllRooms();
|
||||
$eventTimeZone = Carbon::now()->timezone;
|
||||
|
||||
foreach ($schedule->getDay() as $day) {
|
||||
foreach ($day->getRoom() as $room) {
|
||||
foreach ($room->getEvent() as $event) {
|
||||
$scheduleEvents[$event->getGuid()] = $event;
|
||||
|
||||
$event->getDate()->subMinutes($minutesBefore);
|
||||
$event->getEndDate()->addMinutes($minutesAfter);
|
||||
$event->setTitle(sprintf('%s [%s]', $event->getTitle(), $event->getLanguage()));
|
||||
$event->getDate()->timezone($eventTimeZone)->subMinutes($minutesBefore);
|
||||
$event->getEndDate()->timezone($eventTimeZone)->addMinutes($minutesAfter);
|
||||
$event->setTitle(
|
||||
$event->getLanguage()
|
||||
? sprintf('%s [%s]', $event->getTitle(), $event->getLanguage())
|
||||
: $event->getTitle()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,17 +476,18 @@ class ImportSchedule extends BaseController
|
|||
$existingShifts = $this->getScheduleShiftsByGuid($scheduleUrl, $scheduleEventsGuidList);
|
||||
foreach ($existingShifts as $shift) {
|
||||
$guid = $shift->guid;
|
||||
$shift = $this->loadShift($shift->shift_id);
|
||||
/** @var Shift $shift */
|
||||
$shift = Shift::with('room')->find($shift->shift_id);
|
||||
$event = $scheduleEvents[$guid];
|
||||
$room = $rooms->where('name', $event->getRoom()->getName())->first();
|
||||
|
||||
if (
|
||||
$shift->title != $event->getTitle()
|
||||
|| $shift->shift_type_id != $shiftType
|
||||
|| Carbon::createFromTimestamp($shift->start) != $event->getDate()
|
||||
|| Carbon::createFromTimestamp($shift->end) != $event->getEndDate()
|
||||
|| $shift->start != $event->getDate()
|
||||
|| $shift->end != $event->getEndDate()
|
||||
|| $shift->room_id != ($room->id ?? '')
|
||||
|| $shift->url != $event->getUrl()
|
||||
|| $shift->url != ($event->getUrl() ?? '')
|
||||
) {
|
||||
$changeEvents[$guid] = $event;
|
||||
}
|
||||
|
@ -515,20 +510,19 @@ class ImportSchedule extends BaseController
|
|||
|
||||
protected function eventFromScheduleShift(ScheduleShift $scheduleShift): Event
|
||||
{
|
||||
$shift = $this->loadShift($scheduleShift->shift_id);
|
||||
$start = Carbon::createFromTimestamp($shift->start);
|
||||
$end = Carbon::createFromTimestamp($shift->end);
|
||||
$duration = $start->diff($end);
|
||||
/** @var Shift $shift */
|
||||
$shift = Shift::with('room')->find($scheduleShift->shift_id);
|
||||
$duration = $shift->start->diff($shift->end);
|
||||
|
||||
return new Event(
|
||||
$scheduleShift->guid,
|
||||
0,
|
||||
new Room($shift->room_name),
|
||||
new Room($shift->room->name),
|
||||
$shift->title,
|
||||
'',
|
||||
'n/a',
|
||||
Carbon::createFromTimestamp($shift->start),
|
||||
$start->format('H:i'),
|
||||
$shift->start,
|
||||
$shift->start->format('H:i'),
|
||||
$duration->format('%H:%I'),
|
||||
'',
|
||||
'',
|
||||
|
@ -570,31 +564,6 @@ class ImportSchedule extends BaseController
|
|||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return stdClass|null
|
||||
*/
|
||||
protected function loadShift($id): ?stdClass
|
||||
{
|
||||
return $this->db->selectOne(
|
||||
'
|
||||
SELECT
|
||||
s.SID AS id,
|
||||
s.title,
|
||||
s.start,
|
||||
s.end,
|
||||
s.shifttype_id AS shift_type_id,
|
||||
s.RID AS room_id,
|
||||
r.Name AS room_name,
|
||||
s.URL as url
|
||||
FROM Shifts AS s
|
||||
LEFT JOIN rooms r on s.RID = r.id
|
||||
WHERE SID = ?
|
||||
',
|
||||
[$id]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Controller for ical output of users own shifts or any user_shifts filter.
|
||||
|
@ -31,7 +32,7 @@ function user_ical()
|
|||
/**
|
||||
* Renders an ical calendar from given shifts array.
|
||||
*
|
||||
* @param array $shifts Shift
|
||||
* @param Shift[]|Collection $shifts Shift
|
||||
*/
|
||||
function send_ical_from_shifts($shifts)
|
||||
{
|
||||
|
@ -50,25 +51,22 @@ function send_ical_from_shifts($shifts)
|
|||
/**
|
||||
* Renders an ical vevent from given shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function make_ical_entry_from_shift($shift)
|
||||
function make_ical_entry_from_shift(Shift $shift)
|
||||
{
|
||||
$start = Carbon::createFromTimestamp($shift['start']);
|
||||
$end = Carbon::createFromTimestamp($shift['end']);
|
||||
|
||||
$output = "BEGIN:VEVENT\r\n";
|
||||
$output .= 'UID:' . md5($shift['start'] . $shift['end'] . $shift['name']) . "\r\n";
|
||||
$output .= 'SUMMARY:' . str_replace("\n", "\\n", $shift['name'])
|
||||
. ' (' . str_replace("\n", "\\n", $shift['title']) . ")\r\n";
|
||||
if (isset($shift['Comment'])) {
|
||||
$output .= 'DESCRIPTION:' . str_replace("\n", "\\n", $shift['Comment']) . "\r\n";
|
||||
$output .= 'UID:' . md5($shift->start->timestamp . $shift->end->timestamp . $shift->shiftType->name) . "\r\n";
|
||||
$output .= 'SUMMARY:' . str_replace("\n", "\\n", $shift->shiftType->name)
|
||||
. ' (' . str_replace("\n", "\\n", $shift->title) . ")\r\n";
|
||||
if (isset($shift->Comment)) {
|
||||
$output .= 'DESCRIPTION:' . str_replace("\n", "\\n", $shift->Comment) . "\r\n";
|
||||
}
|
||||
$output .= 'DTSTAMP:' . $start->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'DTSTART:' . $start->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'DTEND:' . $end->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'LOCATION:' . $shift['Name'] . "\r\n";
|
||||
$output .= 'DTSTAMP:' . $shift->start->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'DTSTART:' . $shift->start->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'DTEND:' . $shift->end->utc()->format('Ymd\THis\Z') . "\r\n";
|
||||
$output .= 'LOCATION:' . $shift->room->name . "\r\n";
|
||||
$output .= "END:VEVENT\r\n";
|
||||
return $output;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Database\Db;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
||||
/**
|
||||
|
@ -56,14 +57,12 @@ function user_myshifts()
|
|||
`ShiftEntry`.`Comment`,
|
||||
`ShiftEntry`.`UID`,
|
||||
`shift_types`.`name`,
|
||||
`Shifts`.*,
|
||||
`rooms`.`name` as room_name,
|
||||
`shifts`.*,
|
||||
`angel_types`.`name` AS `angel_type`
|
||||
FROM `ShiftEntry`
|
||||
JOIN `angel_types` ON (`ShiftEntry`.`TID` = `angel_types`.`id`)
|
||||
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
|
||||
JOIN `shift_types` ON (`shift_types`.`id` = `Shifts`.`shifttype_id`)
|
||||
JOIN `rooms` ON (`Shifts`.`RID` = `rooms`.`id`)
|
||||
JOIN `shifts` ON (`ShiftEntry`.`SID` = `shifts`.`id`)
|
||||
JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`)
|
||||
WHERE `ShiftEntry`.`id`=?
|
||||
AND `UID`=?
|
||||
LIMIT 1
|
||||
|
@ -74,8 +73,11 @@ function user_myshifts()
|
|||
]
|
||||
);
|
||||
if (!empty($shift)) {
|
||||
$freeloaded = $shift['freeloaded'];
|
||||
$freeload_comment = $shift['freeload_comment'];
|
||||
/** @var Shift $shift */
|
||||
$shift = (new Shift())->forceFill($shift);
|
||||
|
||||
$freeloaded = $shift->freeloaded;
|
||||
$freeload_comment = $shift->freeloaded_comment;
|
||||
|
||||
if ($request->hasPostData('submit')) {
|
||||
$valid = true;
|
||||
|
@ -88,8 +90,8 @@ function user_myshifts()
|
|||
}
|
||||
}
|
||||
|
||||
$comment = $shift['Comment'];
|
||||
$user_source = User::find($shift['UID']);
|
||||
$comment = $shift->Comment;
|
||||
$user_source = User::find($shift->UID);
|
||||
if (auth()->user()->id == $user_source->id) {
|
||||
$comment = strip_request_item_nl('comment');
|
||||
}
|
||||
|
@ -103,9 +105,10 @@ function user_myshifts()
|
|||
]);
|
||||
|
||||
engelsystem_log(
|
||||
'Updated ' . User_Nick_render($user_source, true) . '\'s shift ' . $shift['name']
|
||||
. ' from ' . date('Y-m-d H:i', $shift['start'])
|
||||
. ' to ' . date('Y-m-d H:i', $shift['end'])
|
||||
'Updated ' . User_Nick_render($user_source, true) . '\'s shift '
|
||||
. $shift->title . ' / ' . $shift->shiftType->name
|
||||
. ' from ' . $shift->start->format('Y-m-d H:i')
|
||||
. ' to ' . $shift->end->format('Y-m-d H:i')
|
||||
. ' with comment ' . $comment
|
||||
. '. Freeloaded: ' . ($freeloaded ? 'YES Comment: ' . $freeload_comment : 'NO')
|
||||
);
|
||||
|
@ -116,13 +119,13 @@ function user_myshifts()
|
|||
|
||||
return ShiftEntry_edit_view(
|
||||
$shifts_user,
|
||||
date('Y-m-d H:i', $shift['start']) . ', ' . shift_length($shift),
|
||||
$shift['room_name'],
|
||||
$shift['name'],
|
||||
$shift['angel_type'],
|
||||
$shift['Comment'],
|
||||
$shift['freeloaded'],
|
||||
$shift['freeload_comment'],
|
||||
$shift->start->format('Y-m-d H:i') . ', ' . shift_length($shift),
|
||||
$shift->room->name,
|
||||
$shift->shiftType->name,
|
||||
$shift->angel_type,
|
||||
$shift->Comment,
|
||||
$shift->freeloaded,
|
||||
$shift->freeload_comment,
|
||||
auth()->can('user_shifts_admin')
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -131,8 +131,8 @@ function load_days()
|
|||
{
|
||||
$days = (new Collection(Db::select(
|
||||
'
|
||||
SELECT DISTINCT DATE(FROM_UNIXTIME(`start`)) AS `id`, DATE(FROM_UNIXTIME(`start`)) AS `name`
|
||||
FROM `Shifts`
|
||||
SELECT DISTINCT DATE(`start`) AS `id`, DATE(`start`) AS `name`
|
||||
FROM `shifts`
|
||||
ORDER BY `id`, `name`
|
||||
'
|
||||
)))
|
||||
|
@ -253,10 +253,10 @@ function view_user_shifts()
|
|||
'name' => __('free')
|
||||
]
|
||||
];
|
||||
$start_day = date('Y-m-d', $shiftsFilter->getStartTime());
|
||||
$start_time = date('H:i', $shiftsFilter->getStartTime());
|
||||
$end_day = date('Y-m-d', $shiftsFilter->getEndTime());
|
||||
$end_time = date('H:i', $shiftsFilter->getEndTime());
|
||||
$start_day = $shiftsFilter->getStart()->format('Y-m-d');
|
||||
$start_time = $shiftsFilter->getStart()->format('H:i');
|
||||
$end_day = $shiftsFilter->getEnd()->format('Y-m-d');
|
||||
$end_time = $shiftsFilter->getEnd()->format('H:i');
|
||||
|
||||
if (config('signup_requires_arrival') && !$user->state->arrived) {
|
||||
info(render_user_arrived_hint());
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Engelsystem;
|
||||
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
|
@ -9,17 +10,15 @@ use Exception;
|
|||
*/
|
||||
class ShiftCalendarLane
|
||||
{
|
||||
/** @var array[] */
|
||||
/** @var Shift[] */
|
||||
private $shifts = [];
|
||||
|
||||
/**
|
||||
* ShiftCalendarLane constructor.
|
||||
*
|
||||
* @param string $header
|
||||
* @param int $firstBlockStartTime Unix timestamp
|
||||
* @param int $blockCount
|
||||
*/
|
||||
public function __construct(private $header, private $firstBlockStartTime, private $blockCount)
|
||||
public function __construct(private $header)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -27,10 +26,10 @@ class ShiftCalendarLane
|
|||
* Adds a shift to the lane, but only if it fits.
|
||||
* Returns true on success.
|
||||
*
|
||||
* @param array $shift The shift to add
|
||||
* @param Shift $shift The shift to add
|
||||
* @throws Exception if the shift doesn't fit into the lane.
|
||||
*/
|
||||
public function addShift($shift)
|
||||
public function addShift(Shift $shift)
|
||||
{
|
||||
if ($this->shiftFits($shift)) {
|
||||
$this->shifts[] = $shift;
|
||||
|
@ -43,14 +42,14 @@ class ShiftCalendarLane
|
|||
/**
|
||||
* Returns true if given shift fits into this lane.
|
||||
*
|
||||
* @param array $newShift
|
||||
* @param Shift $newShift
|
||||
* @return bool
|
||||
* @internal param array $shift The shift to fit into this lane
|
||||
*/
|
||||
public function shiftFits($newShift)
|
||||
public function shiftFits(Shift $newShift)
|
||||
{
|
||||
foreach ($this->shifts as $laneShift) {
|
||||
if (!($newShift['start'] >= $laneShift['end'] || $newShift['end'] <= $laneShift['start'])) {
|
||||
if (!($newShift->start >= $laneShift->end || $newShift->end <= $laneShift->start)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ class ShiftCalendarLane
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @return Shift[]
|
||||
*/
|
||||
public function getShifts()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Engelsystem;
|
||||
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
|
||||
class ShiftCalendarRenderer
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ class ShiftCalendarRenderer
|
|||
/**
|
||||
* ShiftCalendarRenderer constructor.
|
||||
*
|
||||
* @param array[] $shifts
|
||||
* @param Shift[] $shifts
|
||||
* @param array[] $needed_angeltypes
|
||||
* @param array[] $shift_entries
|
||||
* @param ShiftsFilter $shiftsFilter
|
||||
|
@ -61,7 +61,7 @@ class ShiftCalendarRenderer
|
|||
/**
|
||||
* Assigns the shifts to different lanes per room if they collide
|
||||
*
|
||||
* @param array[] $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
|
||||
*/
|
||||
private function assignShiftsToLanes($shifts)
|
||||
|
@ -70,20 +70,17 @@ class ShiftCalendarRenderer
|
|||
$lanes = [];
|
||||
|
||||
foreach ($shifts as $shift) {
|
||||
$room_id = $shift['RID'];
|
||||
$room = new Room();
|
||||
$room->name = $shift['room_name'];
|
||||
$room->setAttribute('id', $room_id);
|
||||
$room = $shift->room;
|
||||
$header = Room_name_render($room);
|
||||
if (!isset($lanes[$room_id])) {
|
||||
if (!isset($lanes[$room->id])) {
|
||||
// initialize room with one lane
|
||||
$lanes[$room_id] = [
|
||||
new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot())
|
||||
$lanes[$room->id] = [
|
||||
new ShiftCalendarLane($header)
|
||||
];
|
||||
}
|
||||
// Try to add the shift to the existing lanes for this room
|
||||
$shift_added = false;
|
||||
foreach ($lanes[$room_id] as $lane) {
|
||||
foreach ($lanes[$room->id] as $lane) {
|
||||
/** @var ShiftCalendarLane $lane */
|
||||
if ($lane->shiftFits($shift)) {
|
||||
$lane->addShift($shift);
|
||||
|
@ -93,9 +90,9 @@ class ShiftCalendarRenderer
|
|||
}
|
||||
// If all lanes for this room are busy, create a new lane and add shift to it
|
||||
if (!$shift_added) {
|
||||
$newLane = new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot());
|
||||
$newLane = new ShiftCalendarLane($header);
|
||||
$newLane->addShift($shift);
|
||||
$lanes[$room_id][] = $newLane;
|
||||
$lanes[$room->id][] = $newLane;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,15 +173,15 @@ class ShiftCalendarRenderer
|
|||
$rendered_until = $this->getFirstBlockStartTime();
|
||||
|
||||
foreach ($lane->getShifts() as $shift) {
|
||||
while ($rendered_until + ShiftCalendarRenderer::SECONDS_PER_ROW <= $shift['start']) {
|
||||
while ($rendered_until + ShiftCalendarRenderer::SECONDS_PER_ROW <= $shift->start->timestamp) {
|
||||
$html .= $this->renderTick($rendered_until);
|
||||
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
|
||||
}
|
||||
|
||||
list ($shift_height, $shift_html) = $shift_renderer->render(
|
||||
$shift,
|
||||
$this->needed_angeltypes[$shift['SID']],
|
||||
$this->shift_entries[$shift['SID']],
|
||||
$this->needed_angeltypes[$shift->id],
|
||||
$this->shift_entries[$shift->id],
|
||||
auth()->user()
|
||||
);
|
||||
$html .= $shift_html;
|
||||
|
@ -256,15 +253,15 @@ class ShiftCalendarRenderer
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array[] $shifts
|
||||
* @param Shift[] $shifts
|
||||
* @return int
|
||||
*/
|
||||
private function calcFirstBlockStartTime($shifts)
|
||||
{
|
||||
$start_time = $this->shiftsFilter->getEndTime();
|
||||
foreach ($shifts as $shift) {
|
||||
if ($shift['start'] < $start_time) {
|
||||
$start_time = $shift['start'];
|
||||
if ($shift->start->timestamp < $start_time) {
|
||||
$start_time = $shift->start->timestamp;
|
||||
}
|
||||
}
|
||||
return ShiftCalendarRenderer::SECONDS_PER_ROW * floor(
|
||||
|
@ -274,15 +271,15 @@ class ShiftCalendarRenderer
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array[] $shifts
|
||||
* @param Shift[] $shifts
|
||||
* @return int
|
||||
*/
|
||||
private function calcLastBlockEndTime($shifts)
|
||||
{
|
||||
$end_time = $this->shiftsFilter->getStartTime();
|
||||
foreach ($shifts as $shift) {
|
||||
if ($shift['end'] > $end_time) {
|
||||
$end_time = $shift['end'];
|
||||
if ($shift->end->timestamp > $end_time) {
|
||||
$end_time = $shift->end->timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Engelsystem;
|
||||
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
||||
use function theme_type;
|
||||
|
@ -16,17 +16,17 @@ class ShiftCalendarShiftRenderer
|
|||
/**
|
||||
* Renders a shift
|
||||
*
|
||||
* @param array $shift The shift to render
|
||||
* @param Shift $shift The shift to render
|
||||
* @param array[] $needed_angeltypes
|
||||
* @param array $shift_entries
|
||||
* @param User $user The user who is viewing the shift calendar
|
||||
* @return array
|
||||
*/
|
||||
public function render($shift, $needed_angeltypes, $shift_entries, $user)
|
||||
public function render(Shift $shift, $needed_angeltypes, $shift_entries, $user)
|
||||
{
|
||||
$info_text = '';
|
||||
if ($shift['title'] != '') {
|
||||
$info_text = icon('info-circle') . $shift['title'] . '<br>';
|
||||
if ($shift->title != '') {
|
||||
$info_text = icon('info-circle') . $shift->title . '<br>';
|
||||
}
|
||||
list($shift_signup_state, $shifts_row) = $this->renderShiftNeededAngeltypes(
|
||||
$shift,
|
||||
|
@ -37,12 +37,10 @@ class ShiftCalendarShiftRenderer
|
|||
|
||||
$class = $this->classForSignupState($shift_signup_state);
|
||||
|
||||
$blocks = ceil(($shift['end'] - $shift['start']) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
||||
$blocks = ceil(($shift->end->timestamp - $shift->start->timestamp) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
||||
$blocks = max(1, $blocks);
|
||||
|
||||
$room = new Room();
|
||||
$room->name = $shift['room_name'];
|
||||
$room->setAttribute('id', $shift['RID']);
|
||||
$room = $shift->room;
|
||||
|
||||
return [
|
||||
$blocks,
|
||||
|
@ -82,13 +80,13 @@ class ShiftCalendarShiftRenderer
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param array[] $needed_angeltypes
|
||||
* @param array[] $shift_entries
|
||||
* @param User $user
|
||||
* @return array
|
||||
*/
|
||||
private function renderShiftNeededAngeltypes($shift, $needed_angeltypes, $shift_entries, $user)
|
||||
private function renderShiftNeededAngeltypes(Shift $shift, $needed_angeltypes, $shift_entries, $user)
|
||||
{
|
||||
$shift_entries_filtered = [];
|
||||
foreach ($needed_angeltypes as $needed_angeltype) {
|
||||
|
@ -146,14 +144,14 @@ class ShiftCalendarShiftRenderer
|
|||
/**
|
||||
* Renders a list entry containing the needed angels for an angeltype
|
||||
*
|
||||
* @param array $shift The shift which is rendered
|
||||
* @param Shift $shift The shift which is rendered
|
||||
* @param array[] $shift_entries
|
||||
* @param array $angeltype The angeltype, containing information about needed angeltypes
|
||||
* and already signed up angels
|
||||
* @param User $user The user who is viewing the shift calendar
|
||||
* @return array
|
||||
*/
|
||||
private function renderShiftNeededAngeltype($shift, $shift_entries, $angeltype, $user)
|
||||
private function renderShiftNeededAngeltype(Shift $shift, $shift_entries, $angeltype, $user)
|
||||
{
|
||||
$angeltype = (new AngelType())->forceFill($angeltype);
|
||||
$entry_list = [];
|
||||
|
@ -259,30 +257,30 @@ class ShiftCalendarShiftRenderer
|
|||
/**
|
||||
* Renders the shift header
|
||||
*
|
||||
* @param array $shift The shift
|
||||
* @param Shift $shift The shift
|
||||
* @param string $class The shift state class
|
||||
* @return string
|
||||
*/
|
||||
private function renderShiftHead($shift, $class, $needed_angeltypes_count)
|
||||
private function renderShiftHead(Shift $shift, $class, $needed_angeltypes_count)
|
||||
{
|
||||
$header_buttons = '';
|
||||
if (auth()->can('admin_shifts')) {
|
||||
$header_buttons = '<div class="ms-auto d-print-none">' . table_buttons([
|
||||
button(
|
||||
page_link_to('user_shifts', ['edit_shift' => $shift['SID']]),
|
||||
page_link_to('user_shifts', ['edit_shift' => $shift->id]),
|
||||
icon('pencil'),
|
||||
"btn-$class btn-sm border-light text-white"
|
||||
),
|
||||
button(
|
||||
page_link_to('user_shifts', ['delete_shift' => $shift['SID']]),
|
||||
page_link_to('user_shifts', ['delete_shift' => $shift->id]),
|
||||
icon('trash'),
|
||||
"btn-$class btn-sm border-light text-white"
|
||||
)
|
||||
]) . '</div>';
|
||||
}
|
||||
$shift_heading = date('H:i', $shift['start']) . ' ‐ '
|
||||
. date('H:i', $shift['end']) . ' — '
|
||||
. $shift['name'];
|
||||
$shift_heading = $shift->start->format('H:i') . ' ‐ '
|
||||
. $shift->end->format('H:i') . ' — '
|
||||
. $shift->shiftType->name;
|
||||
|
||||
if ($needed_angeltypes_count > 0) {
|
||||
$shift_heading = '<span class="badge bg-light text-danger me-1">' . $needed_angeltypes_count . '</span> ' . $shift_heading;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
|
||||
/**
|
||||
* Sign off from a user from a shift with admin permissions, asking for ack.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @param User $signoff_user
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
function ShiftEntry_delete_view_admin($shift, AngelType $angeltype, $signoff_user)
|
||||
function ShiftEntry_delete_view_admin(Shift $shift, AngelType $angeltype, User $signoff_user)
|
||||
{
|
||||
return page_with_title(ShiftEntry_delete_title(), [
|
||||
info(sprintf(
|
||||
__('Do you want to sign off %s from shift %s from %s to %s as %s?'),
|
||||
User_Nick_render($signoff_user),
|
||||
$shift['name'],
|
||||
date('Y-m-d H:i', $shift['start']),
|
||||
date('Y-m-d H:i', $shift['end']),
|
||||
$shift->shiftType->name,
|
||||
$shift->start->format('Y-m-d H:i'),
|
||||
$shift->end->format('Y-m-d H:i'),
|
||||
$angeltype->name
|
||||
), true),
|
||||
form([
|
||||
|
@ -37,20 +37,20 @@ function ShiftEntry_delete_view_admin($shift, AngelType $angeltype, $signoff_use
|
|||
/**
|
||||
* Sign off from a shift, asking for ack.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @param int $signoff_user_id
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
function ShiftEntry_delete_view($shift, AngelType $angeltype, $signoff_user_id)
|
||||
function ShiftEntry_delete_view(Shift $shift, AngelType $angeltype, $signoff_user_id)
|
||||
{
|
||||
return page_with_title(ShiftEntry_delete_title(), [
|
||||
info(sprintf(
|
||||
__('Do you want to sign off from your shift %s from %s to %s as %s?'),
|
||||
$shift['name'],
|
||||
date('Y-m-d H:i', $shift['start']),
|
||||
date('Y-m-d H:i', $shift['end']),
|
||||
$shift->shiftType->name,
|
||||
$shift->start->format('Y-m-d H:i'),
|
||||
$shift->end->format('Y-m-d H:i'),
|
||||
$angeltype->name
|
||||
), true),
|
||||
|
||||
|
@ -74,7 +74,7 @@ function ShiftEntry_delete_title()
|
|||
/**
|
||||
* Admin puts user into shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param Room $room
|
||||
* @param AngelType $angeltype
|
||||
* @param array $angeltypes_select
|
||||
|
@ -83,17 +83,17 @@ function ShiftEntry_delete_title()
|
|||
* @return string
|
||||
*/
|
||||
function ShiftEntry_create_view_admin(
|
||||
$shift,
|
||||
Shift $shift,
|
||||
Room $room,
|
||||
AngelType $angeltype,
|
||||
$angeltypes_select,
|
||||
$signup_user,
|
||||
$users_select
|
||||
) {
|
||||
$start = Carbon::createFromTimestamp($shift['start'])->format(__('Y-m-d H:i'));
|
||||
$start = $shift->start->format(__('Y-m-d H:i'));
|
||||
return page_with_title(
|
||||
ShiftEntry_create_title() . ': ' . $shift['name']
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift['start'] . '">%c</small>',
|
||||
ShiftEntry_create_title() . ': ' . $shift->shiftType->name
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
|
||||
[
|
||||
Shift_view_header($shift, $room),
|
||||
info(__('Do you want to sign up the following user for this shift?'), true),
|
||||
|
@ -109,19 +109,19 @@ function ShiftEntry_create_view_admin(
|
|||
/**
|
||||
* Supporter puts user into shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param Room $room
|
||||
* @param AngelType $angeltype
|
||||
* @param User $signup_user
|
||||
* @param array $users_select
|
||||
* @return string
|
||||
*/
|
||||
function ShiftEntry_create_view_supporter($shift, Room $room, AngelType $angeltype, $signup_user, $users_select)
|
||||
function ShiftEntry_create_view_supporter(Shift $shift, Room $room, AngelType $angeltype, $signup_user, $users_select)
|
||||
{
|
||||
$start = Carbon::createFromTimestamp($shift['start'])->format(__('Y-m-d H:i'));
|
||||
$start = $shift->start->format(__('Y-m-d H:i'));
|
||||
return page_with_title(
|
||||
ShiftEntry_create_title() . ': ' . $shift['name']
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift['start'] . '">%c</small>',
|
||||
ShiftEntry_create_title() . ': ' . $shift->shiftType->name
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
|
||||
[
|
||||
Shift_view_header($shift, $room),
|
||||
info(sprintf(
|
||||
|
@ -139,18 +139,18 @@ function ShiftEntry_create_view_supporter($shift, Room $room, AngelType $angelty
|
|||
/**
|
||||
* User joining a shift.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param Room $room
|
||||
* @param AngelType $angeltype
|
||||
* @param string $comment
|
||||
* @return string
|
||||
*/
|
||||
function ShiftEntry_create_view_user($shift, Room $room, AngelType $angeltype, $comment)
|
||||
function ShiftEntry_create_view_user(Shift $shift, Room $room, AngelType $angeltype, $comment)
|
||||
{
|
||||
$start = Carbon::createFromTimestamp($shift['start'])->format(__('Y-m-d H:i'));
|
||||
$start = $shift->start->format(__('Y-m-d H:i'));
|
||||
return page_with_title(
|
||||
ShiftEntry_create_title() . ': ' . $shift['name']
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift['start'] . '">%c</small>',
|
||||
ShiftEntry_create_title() . ': ' . $shift->shiftType->name
|
||||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
|
||||
[
|
||||
Shift_view_header($shift, $room),
|
||||
info(sprintf(__('Do you want to sign up for this shift as %s?'), AngelType_name_render($angeltype)), true),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Models\UserAngelType;
|
||||
|
@ -12,35 +12,35 @@ use Illuminate\Support\Collection;
|
|||
/**
|
||||
* Renders the basic shift view header.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param Room $room
|
||||
* @return string HTML
|
||||
*/
|
||||
function Shift_view_header($shift, Room $room)
|
||||
function Shift_view_header(Shift $shift, Room $room)
|
||||
{
|
||||
return div('row', [
|
||||
div('col-sm-3 col-xs-6', [
|
||||
'<h4>' . __('Title') . '</h4>',
|
||||
'<p class="lead">'
|
||||
. ($shift['URL'] != ''
|
||||
? '<a href="' . $shift['URL'] . '">' . $shift['title'] . '</a>'
|
||||
: $shift['title'])
|
||||
. ($shift->url != ''
|
||||
? '<a href="' . $shift->url . '">' . $shift->title . '</a>'
|
||||
: $shift->title)
|
||||
. '</p>'
|
||||
]),
|
||||
div('col-sm-3 col-xs-6', [
|
||||
'<h4>' . __('Start') . '</h4>',
|
||||
'<p class="lead' . (time() >= $shift['start'] ? ' text-success' : '') . '">',
|
||||
icon('calendar-event') . date(__('Y-m-d'), $shift['start']),
|
||||
'<p class="lead' . (time() >= $shift->start->timestamp ? ' text-success' : '') . '">',
|
||||
icon('calendar-event') . $shift->start->format(__('Y-m-d')),
|
||||
'<br />',
|
||||
icon('clock') . date('H:i', $shift['start']),
|
||||
icon('clock') . $shift->start->format('H:i'),
|
||||
'</p>'
|
||||
]),
|
||||
div('col-sm-3 col-xs-6', [
|
||||
'<h4>' . __('End') . '</h4>',
|
||||
'<p class="lead' . (time() >= $shift['end'] ? ' text-success' : '') . '">',
|
||||
icon('calendar-event') . date(__('Y-m-d'), $shift['end']),
|
||||
'<p class="lead' . (time() >= $shift->end->timestamp ? ' text-success' : '') . '">',
|
||||
icon('calendar-event') . $shift->end->format(__('Y-m-d')),
|
||||
'<br />',
|
||||
icon('clock') . date('H:i', $shift['end']),
|
||||
icon('clock') . $shift->end->format('H:i'),
|
||||
'</p>'
|
||||
]),
|
||||
div('col-sm-3 col-xs-6', [
|
||||
|
@ -51,35 +51,35 @@ function Shift_view_header($shift, Room $room)
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function Shift_editor_info_render($shift)
|
||||
function Shift_editor_info_render(Shift $shift)
|
||||
{
|
||||
$info = [];
|
||||
if (!empty($shift['created_by_user_id'])) {
|
||||
if (!empty($shift->created_by)) {
|
||||
$info[] = sprintf(
|
||||
icon('plus-lg') . __('created at %s by %s'),
|
||||
date('Y-m-d H:i', $shift['created_at_timestamp']),
|
||||
User_Nick_render(User::find($shift['created_by_user_id']))
|
||||
$shift->created_at->format('Y-m-d H:i'),
|
||||
User_Nick_render($shift->createdBy)
|
||||
);
|
||||
}
|
||||
if (!empty($shift['edited_by_user_id'])) {
|
||||
if (!empty($shift->updated_by)) {
|
||||
$info[] = sprintf(
|
||||
icon('pencil') . __('edited at %s by %s'),
|
||||
date('Y-m-d H:i', $shift['edited_at_timestamp']),
|
||||
User_Nick_render(User::find($shift['edited_by_user_id']))
|
||||
$shift->updated_at->format('Y-m-d H:i'),
|
||||
User_Nick_render($shift->updatedBy)
|
||||
);
|
||||
}
|
||||
return join('<br />', $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param AngelType $angeltype
|
||||
* @return string
|
||||
*/
|
||||
function Shift_signup_button_render($shift, AngelType $angeltype)
|
||||
function Shift_signup_button_render(Shift $shift, AngelType $angeltype)
|
||||
{
|
||||
/** @var UserAngelType|null $user_angeltype */
|
||||
$user_angeltype = UserAngelType::whereUserId(auth()->user()->id)
|
||||
|
@ -109,14 +109,14 @@ function Shift_signup_button_render($shift, AngelType $angeltype)
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param ShiftType $shifttype
|
||||
* @param Room $room
|
||||
* @param AngelType[]|Collection $angeltypes_source
|
||||
* @param ShiftSignupState $shift_signup_state
|
||||
* @return string
|
||||
*/
|
||||
function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source, ShiftSignupState $shift_signup_state)
|
||||
function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_source, ShiftSignupState $shift_signup_state)
|
||||
{
|
||||
$shift_admin = auth()->can('admin_shifts');
|
||||
$user_shift_admin = auth()->can('user_shifts_admin');
|
||||
|
@ -131,12 +131,12 @@ function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source
|
|||
}
|
||||
|
||||
$needed_angels = '';
|
||||
$neededAngels = new Collection($shift['NeedAngels']);
|
||||
$neededAngels = new Collection($shift->neededAngels);
|
||||
foreach ($neededAngels as $needed_angeltype) {
|
||||
$needed_angels .= Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin);
|
||||
}
|
||||
|
||||
$shiftEntry = new Collection($shift['ShiftEntry']);
|
||||
$shiftEntry = new Collection($shift->shiftEntry);
|
||||
foreach ($shiftEntry->groupBy('TID') as $angelTypes) {
|
||||
/** @var Collection $angelTypes */
|
||||
$type = $angelTypes->first()['TID'];
|
||||
|
@ -160,10 +160,10 @@ function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source
|
|||
$content[] = info(__('You are signed up for this shift.'), true);
|
||||
}
|
||||
|
||||
if (config('signup_advance_hours') && $shift['start'] > time() + config('signup_advance_hours') * 3600) {
|
||||
if (config('signup_advance_hours') && $shift->start->timestamp > time() + config('signup_advance_hours') * 3600) {
|
||||
$content[] = info(sprintf(
|
||||
__('This shift is in the far future and becomes available for signup at %s.'),
|
||||
date(__('Y-m-d') . ' H:i', $shift['start'] - config('signup_advance_hours') * 3600)
|
||||
date(__('Y-m-d') . ' H:i', $shift->start->timestamp - config('signup_advance_hours') * 3600)
|
||||
), true);
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source
|
|||
div('col-sm-6', [
|
||||
'<h2>' . __('Description') . '</h2>',
|
||||
$parsedown->parse($shifttype->description),
|
||||
$parsedown->parse((string) $shift['description']),
|
||||
$parsedown->parse($shift->description),
|
||||
])
|
||||
]);
|
||||
|
||||
|
@ -196,10 +196,10 @@ function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source
|
|||
$content[] = Shift_editor_info_render($shift);
|
||||
}
|
||||
|
||||
$start = Carbon::createFromTimestamp($shift['start'])->format(__('Y-m-d H:i'));
|
||||
$start = $shift->start->format(__('Y-m-d H:i'));
|
||||
|
||||
return page_with_title(
|
||||
$shift['name'] . ' <small title="' . $start . '" data-countdown-ts="' . $shift['start'] . '">%c</small>',
|
||||
$shift->shiftType->name . ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
@ -207,11 +207,11 @@ function Shift_view($shift, ShiftType $shifttype, Room $room, $angeltypes_source
|
|||
/**
|
||||
* @param array $needed_angeltype
|
||||
* @param AngelType[]|Collection $angeltypes
|
||||
* @param array[] $shift
|
||||
* @param Shift $shift
|
||||
* @param bool $user_shift_admin
|
||||
* @return string
|
||||
*/
|
||||
function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin)
|
||||
function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, Shift $shift, $user_shift_admin)
|
||||
{
|
||||
$angeltype = $angeltypes[$needed_angeltype['TID']];
|
||||
$angeltype_supporter = auth()->user()->isAngelTypeSupporter($angeltype)
|
||||
|
@ -242,7 +242,7 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shi
|
|||
);
|
||||
|
||||
$angels = [];
|
||||
foreach ($shift['ShiftEntry'] as $shift_entry) {
|
||||
foreach ($shift->shiftEntry as $shift_entry) {
|
||||
if ($shift_entry['TID'] == $needed_angeltype['TID']) {
|
||||
$angels[] = Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter, $shift);
|
||||
}
|
||||
|
@ -258,10 +258,10 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shi
|
|||
* @param array $shift_entry
|
||||
* @param bool $user_shift_admin
|
||||
* @param bool $angeltype_supporter
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter, $shift)
|
||||
function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter, Shift $shift)
|
||||
{
|
||||
$entry = User_Nick_render(User::find($shift_entry['UID']));
|
||||
if ($shift_entry['freeloaded']) {
|
||||
|
@ -288,14 +288,14 @@ function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angelty
|
|||
/**
|
||||
* Calc shift length in format 12:23h.
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @return string
|
||||
*/
|
||||
function shift_length($shift)
|
||||
function shift_length(Shift $shift)
|
||||
{
|
||||
$length = floor(($shift['end'] - $shift['start']) / (60 * 60)) . ':';
|
||||
$length = floor(($shift->end->timestamp - $shift->start->timestamp) / (60 * 60)) . ':';
|
||||
$length .= str_pad(
|
||||
(($shift['end'] - $shift['start']) % (60 * 60)) / 60,
|
||||
(($shift->end->timestamp - $shift->start->timestamp) % (60 * 60)) / 60,
|
||||
2,
|
||||
'0',
|
||||
STR_PAD_LEFT
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\AngelType;
|
||||
use Engelsystem\Models\Group;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Models\Worklog;
|
||||
use Illuminate\Support\Collection;
|
||||
|
@ -196,35 +196,39 @@ function User_shift_state_render($user)
|
|||
return '';
|
||||
}
|
||||
|
||||
$upcoming_shifts = ShiftEntries_upcoming_for_user($user->id);
|
||||
$upcoming_shifts = ShiftEntries_upcoming_for_user($user);
|
||||
if (empty($upcoming_shifts)) {
|
||||
return '<span class="text-success">' . __('Free') . '</span>';
|
||||
}
|
||||
|
||||
$nextShift = array_shift($upcoming_shifts);
|
||||
|
||||
$start = Carbon::createFromTimestamp($nextShift['start'])->format(__('Y-m-d H:i'));
|
||||
$start = Carbon::make($nextShift['start']);
|
||||
$end = Carbon::make($nextShift['end']);
|
||||
$startFormat = $start->format(__('Y-m-d H:i'));
|
||||
$endFormat = $end->format(__('Y-m-d H:i'));
|
||||
$startTimestamp = $start->timestamp;
|
||||
$endTimestamp = $end->timestamp;
|
||||
|
||||
if ($nextShift['start'] > time()) {
|
||||
if ($nextShift['start'] - time() > 3600) {
|
||||
return '<span class="text-success" title="' . $start . '" data-countdown-ts="' . $nextShift['start'] . '">'
|
||||
if ($startTimestamp > time()) {
|
||||
if ($startTimestamp - time() > 3600) {
|
||||
return '<span class="text-success" title="' . $startFormat . '" data-countdown-ts="' . $startTimestamp . '">'
|
||||
. __('Next shift %c')
|
||||
. '</span>';
|
||||
}
|
||||
return '<span class="text-warning" title="' . $start . '" data-countdown-ts="' . $nextShift['start'] . '">'
|
||||
return '<span class="text-warning" title="' . $startFormat . '" data-countdown-ts="' . $startTimestamp . '">'
|
||||
. __('Next shift %c')
|
||||
. '</span>';
|
||||
}
|
||||
$halfway = ($nextShift['start'] + $nextShift['end']) / 2;
|
||||
|
||||
$halfway = ($startTimestamp + $endTimestamp) / 2;
|
||||
if (time() < $halfway) {
|
||||
return '<span class="text-danger" title="' . $start . '" data-countdown-ts="' . $nextShift['start'] . '">'
|
||||
return '<span class="text-danger" title="' . $startFormat . '" data-countdown-ts="' . $startTimestamp . '">'
|
||||
. __('Shift started %c')
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
$end = Carbon::createFromTimestamp($nextShift['end'])->format(__('Y-m-d H:i'));
|
||||
return '<span class="text-danger" title="' . $end . '" data-countdown-ts="' . $nextShift['end'] . '">'
|
||||
return '<span class="text-danger" title="' . $endFormat . '" data-countdown-ts="' . $endTimestamp . '">'
|
||||
. __('Shift ends %c')
|
||||
. '</span>';
|
||||
}
|
||||
|
@ -235,15 +239,15 @@ function User_last_shift_render($user)
|
|||
return '';
|
||||
}
|
||||
|
||||
$last_shifts = ShiftEntries_finished_by_user($user->id);
|
||||
$last_shifts = ShiftEntries_finished_by_user($user);
|
||||
if (empty($last_shifts)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$lastShift = array_shift($last_shifts);
|
||||
$end = Carbon::createFromTimestamp($lastShift['end'])->format(__('Y-m-d H:i'));
|
||||
$end = Carbon::make($lastShift['end']);
|
||||
|
||||
return '<span title="' . $end . '" data-countdown-ts="' . $lastShift['end'] . '">'
|
||||
return '<span title="' . $end->format(__('Y-m-d H:i')) . '" data-countdown-ts="' . $end->timestamp . '">'
|
||||
. __('Shift ended %c')
|
||||
. '</span>';
|
||||
}
|
||||
|
@ -275,44 +279,44 @@ function User_view_shiftentries($needed_angel_type)
|
|||
/**
|
||||
* Helper that renders a shift line for user view
|
||||
*
|
||||
* @param array $shift
|
||||
* @param Shift $shift
|
||||
* @param User $user_source
|
||||
* @param bool $its_me
|
||||
* @return array
|
||||
*/
|
||||
function User_view_myshift($shift, $user_source, $its_me)
|
||||
function User_view_myshift(Shift $shift, $user_source, $its_me)
|
||||
{
|
||||
$shift_info = '<a href="' . shift_link($shift) . '">' . $shift['name'] . '</a>';
|
||||
if ($shift['title']) {
|
||||
$shift_info .= '<br /><a href="' . shift_link($shift) . '">' . $shift['title'] . '</a>';
|
||||
$shift_info = '<a href="' . shift_link($shift) . '">' . $shift->shiftType->name . '</a>';
|
||||
if ($shift->title) {
|
||||
$shift_info .= '<br /><a href="' . shift_link($shift) . '">' . $shift->title . '</a>';
|
||||
}
|
||||
foreach ($shift['needed_angeltypes'] as $needed_angel_type) {
|
||||
foreach ($shift->needed_angeltypes as $needed_angel_type) {
|
||||
$shift_info .= User_view_shiftentries($needed_angel_type);
|
||||
}
|
||||
|
||||
$myshift = [
|
||||
'date' => icon('calendar-event')
|
||||
. date('Y-m-d', $shift['start']) . '<br>'
|
||||
. icon('clock-history') . date('H:i', $shift['start'])
|
||||
. $shift->start->format('Y-m-d') . '<br>'
|
||||
. icon('clock-history') . $shift->start->format('H:i')
|
||||
. ' - '
|
||||
. date('H:i', $shift['end']),
|
||||
'duration' => sprintf('%.2f', ($shift['end'] - $shift['start']) / 3600) . ' h',
|
||||
'room' => Room_name_render(Room::find($shift['RID'])),
|
||||
. $shift->end->format('H:i'),
|
||||
'duration' => sprintf('%.2f', ($shift->end->timestamp - $shift->start->timestamp) / 3600) . ' h',
|
||||
'room' => Room_name_render($shift->room),
|
||||
'shift_info' => $shift_info,
|
||||
'comment' => ''
|
||||
];
|
||||
|
||||
if ($its_me) {
|
||||
$myshift['comment'] = $shift['Comment'];
|
||||
$myshift['comment'] = $shift->Comment;
|
||||
}
|
||||
|
||||
if ($shift['freeloaded']) {
|
||||
if ($shift->freeloaded) {
|
||||
$myshift['duration'] = '<p class="text-danger">'
|
||||
. sprintf('%.2f', -($shift['end'] - $shift['start']) / 3600 * 2) . ' h'
|
||||
. sprintf('%.2f', -($shift->end->timestamp - $shift->start->timestamp) / 3600 * 2) . ' h'
|
||||
. '</p>';
|
||||
if (auth()->can('user_shifts_admin')) {
|
||||
$myshift['comment'] .= '<br />'
|
||||
. '<p class="text-danger">' . __('Freeloaded') . ': ' . $shift['freeload_comment'] . '</p>';
|
||||
. '<p class="text-danger">' . __('Freeloaded') . ': ' . $shift->freeload_comment . '</p>';
|
||||
} else {
|
||||
$myshift['comment'] .= '<br /><p class="text-danger">' . __('Freeloaded') . '</p>';
|
||||
}
|
||||
|
@ -323,12 +327,12 @@ function User_view_myshift($shift, $user_source, $its_me)
|
|||
];
|
||||
if ($its_me || auth()->can('user_shifts_admin')) {
|
||||
$myshift['actions'][] = button(
|
||||
page_link_to('user_myshifts', ['edit' => $shift['id'], 'id' => $user_source->id]),
|
||||
page_link_to('user_myshifts', ['edit' => $shift->shift_entry_id, 'id' => $user_source->id]),
|
||||
icon('pencil') . __('edit'),
|
||||
'btn-sm'
|
||||
);
|
||||
}
|
||||
if (Shift_signout_allowed($shift, (new AngelType())->forceFill(['id' => $shift['TID']]), $user_source->id)) {
|
||||
if (Shift_signout_allowed($shift, (new AngelType())->forceFill(['id' => $shift->TID]), $user_source->id)) {
|
||||
$myshift['actions'][] = button(
|
||||
shift_entry_delete_link($shift),
|
||||
icon('trash') . __('sign off'),
|
||||
|
@ -343,7 +347,7 @@ function User_view_myshift($shift, $user_source, $its_me)
|
|||
/**
|
||||
* Helper that prepares the shift table for user view
|
||||
*
|
||||
* @param array[] $shifts
|
||||
* @param Shift[]|Collection $shifts
|
||||
* @param User $user_source
|
||||
* @param bool $its_me
|
||||
* @param int $tshirt_score
|
||||
|
@ -365,11 +369,11 @@ function User_view_myshifts(
|
|||
$myshifts_table = [];
|
||||
$timeSum = 0;
|
||||
foreach ($shifts as $shift) {
|
||||
$key = $shift['start'] . '-shift-' . $shift['SID'] . '-' . $shift['id'];
|
||||
$key = $shift->start->timestamp . '-shift-' . $shift->shift_entry_id . $shift->id;
|
||||
$myshifts_table[$key] = User_view_myshift($shift, $user_source, $its_me);
|
||||
|
||||
if (!$shift['freeloaded']) {
|
||||
$timeSum += ($shift['end'] - $shift['start']);
|
||||
if (!$shift->freeloaded) {
|
||||
$timeSum += ($shift->end->timestamp - $shift->start->timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +457,7 @@ function User_view_worklog(Worklog $worklog, $admin_user_worklog_privilege)
|
|||
* @param bool $freeloader
|
||||
* @param AngelType[] $user_angeltypes
|
||||
* @param Group[] $user_groups
|
||||
* @param array[] $shifts
|
||||
* @param Shift[]|Collection $shifts
|
||||
* @param bool $its_me
|
||||
* @param int $tshirt_score
|
||||
* @param bool $tshirt_admin
|
||||
|
|
|
@ -15,6 +15,7 @@ use Engelsystem\Models\NewsComment;
|
|||
use Engelsystem\Models\OAuth;
|
||||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\License;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
use Engelsystem\Models\User\PersonalData;
|
||||
|
@ -109,9 +110,9 @@ class Stats
|
|||
{
|
||||
$query = User::query()
|
||||
->join('ShiftEntry', 'ShiftEntry.UID', '=', 'users.id')
|
||||
->join('Shifts', 'Shifts.SID', '=', 'ShiftEntry.SID')
|
||||
->where('Shifts.start', '<=', time())
|
||||
->where('Shifts.end', '>', time());
|
||||
->join('shifts', 'shifts.id', '=', 'ShiftEntry.SID')
|
||||
->where('shifts.start', '<=', Carbon::now())
|
||||
->where('shifts.end', '>', Carbon::now());
|
||||
|
||||
if (!is_null($freeloaded)) {
|
||||
$query->where('ShiftEntry.freeloaded', '=', $freeloaded);
|
||||
|
@ -207,14 +208,14 @@ class Stats
|
|||
{
|
||||
$query = $this
|
||||
->getQuery('ShiftEntry')
|
||||
->join('Shifts', 'Shifts.SID', '=', 'ShiftEntry.SID');
|
||||
->join('shifts', 'shifts.id', '=', 'ShiftEntry.SID');
|
||||
|
||||
if (!is_null($freeloaded)) {
|
||||
$query->where('freeloaded', '=', $freeloaded);
|
||||
}
|
||||
|
||||
if (!is_null($done)) {
|
||||
$query->where('end', ($done == true ? '<' : '>='), time());
|
||||
$query->where('end', ($done ? '<' : '>='), Carbon::now());
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
@ -309,14 +310,9 @@ class Stats
|
|||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function shifts(): int
|
||||
{
|
||||
return $this
|
||||
->getQuery('Shifts')
|
||||
->count();
|
||||
return Shift::count();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,10 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
|
||||
/**
|
||||
|
@ -17,6 +20,8 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
|
|||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
*
|
||||
* @property-read Collection|Shift[] $shifts
|
||||
*
|
||||
* @method static QueryBuilder|Room[] whereId($value)
|
||||
* @method static QueryBuilder|Room[] whereName($value)
|
||||
* @method static QueryBuilder|Room[] whereMapUrl($value)
|
||||
|
@ -39,4 +44,9 @@ class Room extends BaseModel
|
|||
'map_url',
|
||||
'description',
|
||||
];
|
||||
|
||||
public function shifts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Shift::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Collection;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
|
||||
/**
|
||||
|
@ -20,6 +21,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
|
|||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
*
|
||||
* @property-read QueryBuilder|Collection|Shift[] $shifts
|
||||
* @property-read QueryBuilder|Collection|ScheduleShift[] $scheduleShifts
|
||||
* @property-read QueryBuilder|ShiftType $shiftType
|
||||
*
|
||||
|
@ -60,6 +62,11 @@ class Schedule extends BaseModel
|
|||
return $this->hasMany(ScheduleShift::class);
|
||||
}
|
||||
|
||||
public function shifts(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(Shift::class, ScheduleShift::class, 'schedule_id', 'id');
|
||||
}
|
||||
|
||||
public function shiftType(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ShiftType::class, 'shift_type', 'id');
|
||||
|
|
|
@ -12,6 +12,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
|
|||
* @property string $guid
|
||||
*
|
||||
* @property-read QueryBuilder|Schedule $schedule
|
||||
* @property-read QueryBuilder|Shift $shift
|
||||
*
|
||||
* @method static QueryBuilder|ScheduleShift[] whereShiftId($value)
|
||||
* @method static QueryBuilder|ScheduleShift[] whereScheduleId($value)
|
||||
|
@ -38,4 +39,9 @@ class ScheduleShift extends BaseModel
|
|||
{
|
||||
return $this->belongsTo(Schedule::class);
|
||||
}
|
||||
|
||||
public function shift(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Shift::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Models\Shifts;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Models\BaseModel;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $title
|
||||
* @property string $description
|
||||
* @property string $url
|
||||
* @property Carbon $start
|
||||
* @property Carbon $end
|
||||
* @property int $shift_type_id
|
||||
* @property int $room_id
|
||||
* @property string $transaction_id
|
||||
* @property int $created_by
|
||||
* @property int|null $updated_by
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
*
|
||||
* @property-read QueryBuilder|Schedule $schedule
|
||||
* @property-read QueryBuilder|ShiftType $shiftType
|
||||
* @property-read QueryBuilder|Room $room
|
||||
* @property-read QueryBuilder|User $createdBy
|
||||
* @property-read QueryBuilder|User|null $updatedBy
|
||||
*
|
||||
* @method static QueryBuilder|Shift[] whereId($value)
|
||||
* @method static QueryBuilder|Shift[] whereTitle($value)
|
||||
* @method static QueryBuilder|Shift[] whereDescription($value)
|
||||
* @method static QueryBuilder|Shift[] whereUrl($value)
|
||||
* @method static QueryBuilder|Shift[] whereStart($value)
|
||||
* @method static QueryBuilder|Shift[] whereEnd($value)
|
||||
* @method static QueryBuilder|Shift[] whereShiftTypeId($value)
|
||||
* @method static QueryBuilder|Shift[] whereRoomId($value)
|
||||
* @method static QueryBuilder|Shift[] whereTransactionId($value)
|
||||
* @method static QueryBuilder|Shift[] whereCreatedBy($value)
|
||||
* @method static QueryBuilder|Shift[] whereUpdatedBy($value)
|
||||
* @method static QueryBuilder|Shift[] whereCreatedAt($value)
|
||||
* @method static QueryBuilder|Shift[] whereUpdatedAt($value)
|
||||
*/
|
||||
class Shift extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/** @var bool enable timestamps */
|
||||
public $timestamps = true; // phpcs:ignore
|
||||
|
||||
/** @var array<string, string> */
|
||||
protected $casts = [ // phpcs:ignore
|
||||
'shift_type_id' => 'integer',
|
||||
'room_id' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
/** @var array<string> Values that are mass assignable */
|
||||
protected $fillable = [ // phpcs:ignore
|
||||
'title',
|
||||
'description',
|
||||
'url',
|
||||
'start',
|
||||
'end',
|
||||
'shift_type_id',
|
||||
'room_id',
|
||||
'transaction_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
/** @var array<string> Values that are DateTimes */
|
||||
protected $dates = [ // phpcs:ignore
|
||||
'start',
|
||||
'end',
|
||||
];
|
||||
|
||||
public function schedule(): HasOneThrough
|
||||
{
|
||||
return $this->hasOneThrough(Schedule::class, ScheduleShift::class, null, 'id', null, 'schedule_id');
|
||||
}
|
||||
|
||||
public function shiftType(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ShiftType::class);
|
||||
}
|
||||
|
||||
public function room(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Room::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updatedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
|
|||
* @property string $description
|
||||
*
|
||||
* @property-read Collection|Schedule[] $schedules
|
||||
* @property-read Collection|Shift[] $shifts
|
||||
*
|
||||
* @method static QueryBuilder|ShiftType[] whereId($value)
|
||||
* @method static QueryBuilder|ShiftType[] whereName($value)
|
||||
|
@ -35,4 +36,9 @@ class ShiftType extends BaseModel
|
|||
{
|
||||
return $this->hasMany(Schedule::class, 'shift_type');
|
||||
}
|
||||
|
||||
public function shifts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Shift::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use Engelsystem\Models\NewsComment;
|
|||
use Engelsystem\Models\OAuth;
|
||||
use Engelsystem\Models\Privilege;
|
||||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\UserAngelType;
|
||||
use Engelsystem\Models\Worklog;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
@ -53,6 +54,8 @@ use Illuminate\Support\Collection as SupportCollection;
|
|||
* @property-read Collection|Message[] $messagesReceived
|
||||
* @property-read Collection|Message[] $messagesSent
|
||||
* @property-read Collection|Message[] $messages
|
||||
* @property-read Collection|Shift[] $shiftsCreated
|
||||
* @property-read Collection|Shift[] $shiftsUpdated
|
||||
*
|
||||
* @method static QueryBuilder|User[] whereId($value)
|
||||
* @method static QueryBuilder|User[] whereName($value)
|
||||
|
@ -215,9 +218,6 @@ class User extends BaseModel
|
|||
->orderBy('id', 'DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany|QueryBuilder
|
||||
*/
|
||||
public function messagesReceived(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class, 'receiver_id')
|
||||
|
@ -236,4 +236,14 @@ class User extends BaseModel
|
|||
->orderBy('read')
|
||||
->orderBy('id', 'DESC');
|
||||
}
|
||||
|
||||
public function shiftsCreated(): HasMany
|
||||
{
|
||||
return $this->hasMany(Shift::class, 'created_by');
|
||||
}
|
||||
|
||||
public function shiftsUpdated(): HasMany
|
||||
{
|
||||
return $this->hasMany(Shift::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use Engelsystem\Models\NewsComment;
|
|||
use Engelsystem\Models\OAuth;
|
||||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\License;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
use Engelsystem\Models\User\PersonalData;
|
||||
|
@ -176,6 +177,17 @@ class StatsTest extends TestCase
|
|||
$this->assertEquals(4, $stats->rooms());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::shifts
|
||||
*/
|
||||
public function testShifts(): void
|
||||
{
|
||||
Shift::factory(5)->create();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$this->assertEquals(5, $stats->shifts());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::announcements
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@ use Engelsystem\Models\NewsComment;
|
|||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Schedule;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\Contact;
|
||||
use Engelsystem\Models\User\License;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
|
@ -23,27 +24,33 @@ class FactoriesTest extends TestCase
|
|||
{
|
||||
use HasDatabase;
|
||||
|
||||
/** @var string[] */
|
||||
protected array $models = [
|
||||
Contact::class,
|
||||
Faq::class,
|
||||
License::class,
|
||||
Message::class,
|
||||
News::class,
|
||||
NewsComment::class,
|
||||
PasswordReset::class,
|
||||
PersonalData::class,
|
||||
Question::class,
|
||||
Room::class,
|
||||
Schedule::class,
|
||||
Settings::class,
|
||||
State::class,
|
||||
User::class,
|
||||
Worklog::class,
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function factoriesProvider(): array
|
||||
{
|
||||
return [
|
||||
[Contact::class],
|
||||
[Faq::class],
|
||||
[License::class],
|
||||
[Message::class],
|
||||
[News::class],
|
||||
[NewsComment::class],
|
||||
[PasswordReset::class],
|
||||
[PersonalData::class],
|
||||
[Question::class],
|
||||
[Room::class],
|
||||
[Schedule::class],
|
||||
[Settings::class],
|
||||
[Shift::class],
|
||||
[State::class],
|
||||
[User::class],
|
||||
[Worklog::class],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test all existing model factories
|
||||
* Test all model factories
|
||||
*
|
||||
* @covers \Database\Factories\Engelsystem\Models\User\ContactFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\FaqFactory
|
||||
|
@ -57,19 +64,20 @@ class FactoriesTest extends TestCase
|
|||
* @covers \Database\Factories\Engelsystem\Models\RoomFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\Shifts\ScheduleFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\User\SettingsFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\Shifts\ShiftFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\User\StateFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\User\UserFactory
|
||||
* @covers \Database\Factories\Engelsystem\Models\WorklogFactory
|
||||
*
|
||||
* @dataProvider factoriesProvider
|
||||
*/
|
||||
public function testFactories(): void
|
||||
public function testFactories(string $model): void
|
||||
{
|
||||
$this->initDatabase();
|
||||
|
||||
foreach ($this->models as $model) {
|
||||
$instance = (new $model())->factory()->create();
|
||||
$this->assertInstanceOf(Model::class, $instance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Database\Factories\Engelsystem\Models\User\StateFactory
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Models;
|
||||
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
|
||||
class RoomTest extends ModelTest
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Room::shifts
|
||||
*/
|
||||
public function testShifts(): void
|
||||
{
|
||||
$room = new Room(['name' => 'Test room']);
|
||||
$room->save();
|
||||
|
||||
/** @var Shift $shift */
|
||||
Shift::factory()->create(['room_id' => 1]);
|
||||
|
||||
$room = Room::find(1);
|
||||
$this->assertCount(1, $room->shifts);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace Engelsystem\Test\Unit\Models\Shifts;
|
|||
|
||||
use Engelsystem\Models\Shifts\Schedule;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Test\Unit\Models\ModelTest;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
|
@ -11,6 +12,7 @@ class ScheduleShiftTest extends ModelTest
|
|||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\ScheduleShift::schedule
|
||||
* @covers \Engelsystem\Models\Shifts\ScheduleShift::shift
|
||||
*/
|
||||
public function testScheduleShifts(): void
|
||||
{
|
||||
|
@ -22,14 +24,19 @@ class ScheduleShiftTest extends ModelTest
|
|||
'minutes_after' => 15,
|
||||
]);
|
||||
$schedule->save();
|
||||
/** @var Shift $shift */
|
||||
$shift = Shift::factory()->create();
|
||||
|
||||
$scheduleShift = new ScheduleShift(['shift_id' => 1, 'guid' => 'a']);
|
||||
$scheduleShift = new ScheduleShift(['guid' => 'a']);
|
||||
$scheduleShift->schedule()->associate($schedule);
|
||||
$scheduleShift->shift()->associate($shift);
|
||||
$scheduleShift->save();
|
||||
|
||||
/** @var ScheduleShift $scheduleShift */
|
||||
$scheduleShift = (new ScheduleShift())->find(1);
|
||||
$this->assertInstanceOf(BelongsTo::class, $scheduleShift->schedule());
|
||||
$this->assertEquals($schedule->id, $scheduleShift->schedule->id);
|
||||
$this->assertInstanceOf(BelongsTo::class, $scheduleShift->shift());
|
||||
$this->assertEquals($shift->id, $scheduleShift->shift->id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@ namespace Engelsystem\Test\Unit\Models\Shifts;
|
|||
|
||||
use Engelsystem\Models\Shifts\Schedule;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Test\Unit\Models\ModelTest;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class ScheduleTest extends ModelTest
|
||||
{
|
||||
|
@ -32,6 +34,24 @@ class ScheduleTest extends ModelTest
|
|||
$this->assertCount(3, $schedule->scheduleShifts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\Schedule::shifts
|
||||
*/
|
||||
public function testShifts(): void
|
||||
{
|
||||
$schedule = new Schedule($this->data);
|
||||
$schedule->save();
|
||||
|
||||
/** @var Collection|Shift[] $shifts */
|
||||
$shifts = Shift::factory(3)->create();
|
||||
|
||||
(new ScheduleShift(['shift_id' => $shifts[0]->id, 'schedule_id' => $schedule->id, 'guid' => 'a']))->save();
|
||||
(new ScheduleShift(['shift_id' => $shifts[1]->id, 'schedule_id' => $schedule->id, 'guid' => 'b']))->save();
|
||||
(new ScheduleShift(['shift_id' => $shifts[2]->id, 'schedule_id' => $schedule->id, 'guid' => 'c']))->save();
|
||||
|
||||
$this->assertCount(3, $schedule->shifts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\Schedule::shiftType
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Models\Shifts;
|
||||
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Models\Room;
|
||||
use Engelsystem\Models\Shifts\Schedule;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\Models\ModelTest;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class ShiftTest extends ModelTest
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\Shift::shiftType
|
||||
* @covers \Engelsystem\Models\Shifts\Shift::room
|
||||
* @covers \Engelsystem\Models\Shifts\Shift::createdBy
|
||||
* @covers \Engelsystem\Models\Shifts\Shift::updatedBy
|
||||
*/
|
||||
public function testShiftType(): void
|
||||
{
|
||||
/** @var User $user1 */
|
||||
$user1 = User::factory()->create();
|
||||
/** @var User $user2 */
|
||||
$user2 = User::factory()->create();
|
||||
/** @var ShiftType $shiftType */
|
||||
$shiftType = ShiftType::factory()->create();
|
||||
/** @var Room $room */
|
||||
$room = Room::factory()->create();
|
||||
|
||||
$model = new Shift([
|
||||
'title' => 'Test shift',
|
||||
'description' => 'Some description',
|
||||
'url' => 'https://foo.bar/map',
|
||||
'start' => Carbon::now(),
|
||||
'end' => Carbon::now(),
|
||||
'shift_type_id' => $shiftType->id,
|
||||
'room_id' => $room->id,
|
||||
'transaction_id' => '',
|
||||
'created_by' => $user1->id,
|
||||
'updated_by' => $user2->id,
|
||||
]);
|
||||
$model->save();
|
||||
|
||||
$model = Shift::find(1);
|
||||
|
||||
$this->assertEquals($shiftType->id, $model->shiftType->id);
|
||||
$this->assertEquals($room->id, $model->room->id);
|
||||
$this->assertEquals($user1->id, $model->createdBy->id);
|
||||
$this->assertEquals($user2->id, $model->updatedBy->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\Shift::schedule
|
||||
*/
|
||||
public function testSchedule(): void
|
||||
{
|
||||
/** @var Schedule $schedule */
|
||||
$schedule = Schedule::factory()->create();
|
||||
/** @var Collection|Shift[] $shifts */
|
||||
$shifts = Shift::factory(3)->create();
|
||||
|
||||
(new ScheduleShift(['shift_id' => $shifts[0]->id, 'schedule_id' => $schedule->id, 'guid' => 'a']))->save();
|
||||
(new ScheduleShift(['shift_id' => $shifts[1]->id, 'schedule_id' => $schedule->id, 'guid' => 'b']))->save();
|
||||
(new ScheduleShift(['shift_id' => $shifts[2]->id, 'schedule_id' => $schedule->id, 'guid' => 'c']))->save();
|
||||
|
||||
$this->assertEquals(1, Shift::find(1)->schedule->id);
|
||||
$this->assertEquals(1, Shift::find(2)->schedule->id);
|
||||
$this->assertEquals(1, Shift::find(3)->schedule->id);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Engelsystem\Test\Unit\Models\Shifts;
|
||||
|
||||
use Engelsystem\Models\Shifts\Schedule;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Test\Unit\Models\ModelTest;
|
||||
|
||||
|
@ -21,4 +22,17 @@ class ShiftTypeTest extends ModelTest
|
|||
|
||||
$this->assertCount(2, ShiftType::find(1)->schedules);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Models\Shifts\ShiftType::shifts
|
||||
*/
|
||||
public function testShifts(): void
|
||||
{
|
||||
$shiftType = new ShiftType(['name' => 'Another type', 'description' => '']);
|
||||
$shiftType->save();
|
||||
|
||||
Shift::factory()->create(['shift_type_id' => 1]);
|
||||
|
||||
$this->assertCount(1, ShiftType::find(1)->shifts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use Engelsystem\Models\NewsComment;
|
|||
use Engelsystem\Models\OAuth;
|
||||
use Engelsystem\Models\Privilege;
|
||||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\Contact;
|
||||
use Engelsystem\Models\User\HasUserModel;
|
||||
use Engelsystem\Models\User\License;
|
||||
|
@ -103,8 +104,8 @@ class UserTest extends ModelTest
|
|||
'text' => 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.',
|
||||
'is_meeting' => true,
|
||||
],
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -415,4 +416,29 @@ class UserTest extends ModelTest
|
|||
$this->assertContains($question1->id, $answers);
|
||||
$this->assertContains($question2->id, $answers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Models\User\User::shiftsCreated
|
||||
* @covers \Engelsystem\Models\User\User::shiftsUpdated
|
||||
*/
|
||||
public function testShiftsCreatedAndUpdated(): void
|
||||
{
|
||||
($user1 = new User($this->data))->save();
|
||||
($user2 = new User(array_merge($this->data, ['name' => 'foo', 'email' => 'someone@bar.batz'])))->save();
|
||||
|
||||
Shift::factory()->create();
|
||||
Shift::factory()->create(['created_by' => $user1->id]);
|
||||
Shift::factory()->create(['created_by' => $user2->id, 'updated_by' => $user1->id]);
|
||||
Shift::factory()->create(['created_by' => $user1->id, 'updated_by' => $user2->id]);
|
||||
Shift::factory()->create(['created_by' => $user2->id, 'updated_by' => $user2->id]);
|
||||
Shift::factory()->create(['created_by' => $user1->id]);
|
||||
|
||||
$user1 = User::find(1);
|
||||
$this->assertCount(3, $user1->shiftsCreated);
|
||||
$this->assertCount(1, $user1->shiftsUpdated);
|
||||
|
||||
$user2 = User::find(2);
|
||||
$this->assertCount(2, $user2->shiftsCreated);
|
||||
$this->assertCount(2, $user2->shiftsUpdated);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue