diff --git a/db/factories/Shifts/ShiftEntryFactory.php b/db/factories/Shifts/ShiftEntryFactory.php
new file mode 100644
index 00000000..23b3227d
--- /dev/null
+++ b/db/factories/Shifts/ShiftEntryFactory.php
@@ -0,0 +1,29 @@
+faker->optional(.01, false)->boolean();
+
+ return [
+ 'shift_id' => Shift::factory(),
+ 'angel_type_id' => AngelType::factory(),
+ 'user_id' => User::factory(),
+ 'user_comment' => $this->faker->optional(.05, '')->text(),
+ 'freeloaded' => $freeloaded,
+ 'freeloaded_comment' => $freeloaded ? $this->faker->text() : '',
+ ];
+ }
+}
diff --git a/db/migrations/2022_12_30_000000_create_shift_entries_table.php b/db/migrations/2022_12_30_000000_create_shift_entries_table.php
new file mode 100644
index 00000000..b798a33d
--- /dev/null
+++ b/db/migrations/2022_12_30_000000_create_shift_entries_table.php
@@ -0,0 +1,114 @@
+schema->getConnection();
+ $previous = $this->schema->hasTable('ShiftEntry');
+
+ $this->schema->create('shift_entries', function (Blueprint $table): void {
+ $table->increments('id');
+ $this->references($table, 'shifts');
+ $this->references($table, 'angel_types');
+ $this->referencesUser($table);
+
+ $table->mediumText('user_comment')->default('');
+
+ $table->boolean('freeloaded')->default(false)->index();
+ $table->mediumText('freeloaded_comment')->default('');
+
+ $table->index(['angel_type_id', 'shift_id']);
+ });
+
+ if (!$previous) {
+ return;
+ }
+
+ /** @var stdClass[] $records */
+ $records = $connection
+ ->table('ShiftEntry')
+ ->get();
+ foreach ($records as $record) {
+ $connection->table('shift_entries')->insert([
+ 'id' => $record->id,
+ 'shift_id' => $record->SID,
+ 'angel_type_id' => $record->TID,
+ 'user_id' => $record->UID,
+ 'user_comment' => $record->Comment,
+ 'freeloaded' => (bool) $record->freeloaded,
+ 'freeloaded_comment' => $record->freeload_comment,
+ ]);
+ }
+
+ $this->changeReferences(
+ 'ShiftEntry',
+ 'id',
+ 'shift_entries',
+ 'id'
+ );
+
+ $this->schema->drop('ShiftEntry');
+ }
+
+ /**
+ * Recreates the previous table, copies the data and drops the new one
+ */
+ public function down(): void
+ {
+ $connection = $this->schema->getConnection();
+
+ $this->schema->create('ShiftEntry', function (Blueprint $table): void {
+ $table->increments('id');
+ $this->references($table, 'shifts', 'SID')->default(0);
+ $this->references($table, 'angel_types', 'TID')->default(0);
+ $this->references($table, 'users', 'UID')->default(0);
+
+ $table->mediumText('Comment')->nullable();
+
+ $table->mediumText('freeload_comment')->nullable()->default(null);
+ $table->boolean('freeloaded')->index();
+
+ $table->index(['SID', 'TID']);
+ });
+
+ /** @var stdClass[] $records */
+ $records = $connection
+ ->table('shift_entries')
+ ->get();
+ foreach ($records as $record) {
+ $connection->table('ShiftEntry')->insert([
+ 'id' => $record->id,
+ 'SID' => $record->shift_id,
+ 'TID' => $record->angel_type_id,
+ 'UID' => $record->user_id,
+ 'Comment' => $record->user_comment,
+ 'freeloaded' => (bool) $record->freeloaded,
+ 'freeload_comment' => $record->freeloaded_comment,
+ ]);
+ }
+
+ $this->changeReferences(
+ 'shift_entries',
+ 'id',
+ 'ShiftEntry',
+ 'id'
+ );
+
+ $this->schema->drop('shift_entries');
+ }
+}
diff --git a/includes/controller/public_dashboard_controller.php b/includes/controller/public_dashboard_controller.php
index 4b09732e..823f6a86 100644
--- a/includes/controller/public_dashboard_controller.php
+++ b/includes/controller/public_dashboard_controller.php
@@ -107,8 +107,8 @@ function public_dashboard_needed_angels($needed_angels, ShiftsFilter $filter = n
$result = [];
foreach ($needed_angels as $needed_angel) {
$need = $needed_angel['count'] - $needed_angel['taken'];
- if ($need > 0 && (!$filter || in_array($needed_angel['TID'], $filter->getTypes()))) {
- $angeltype = AngelType::find($needed_angel['TID']);
+ if ($need > 0 && (!$filter || in_array($needed_angel['angel_type_id'], $filter->getTypes()))) {
+ $angeltype = AngelType::find($needed_angel['angel_type_id']);
if ($angeltype->show_on_dashboard) {
$result[] = [
'need' => $need,
diff --git a/includes/controller/shift_entries_controller.php b/includes/controller/shift_entries_controller.php
index a06f4d7f..7cd7b352 100644
--- a/includes/controller/shift_entries_controller.php
+++ b/includes/controller/shift_entries_controller.php
@@ -2,6 +2,7 @@
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\Shift;
+use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
use Engelsystem\Models\UserAngelType;
use Engelsystem\ShiftSignupState;
@@ -27,7 +28,7 @@ function shift_entries_controller(): array
return match ($action) {
'create' => shift_entry_create_controller(),
'delete' => shift_entry_delete_controller(),
- default => ['', ''],
+ default => ['', ''],
};
}
@@ -41,7 +42,7 @@ function shift_entry_create_controller(): array
$user = auth()->user();
$request = request();
- if (User_is_freeloader($user)) {
+ if ($user->isFreeloader()) {
throw_redirect(page_link_to('user_myshifts'));
}
@@ -99,14 +100,12 @@ function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype
}
if ($request->hasPostData('submit')) {
- ShiftEntry_create([
- 'SID' => $shift->id,
- 'TID' => $angeltype->id,
- 'UID' => $signup_user->id,
- 'Comment' => '',
- 'freeloaded' => false,
- 'freeload_comment' => ''
- ]);
+ $shiftEntry = new ShiftEntry();
+ $shiftEntry->shift()->associate($shift);
+ $shiftEntry->angelType()->associate($angeltype);
+ $shiftEntry->user()->associate($signup_user);
+ $shiftEntry->save();
+ ShiftEntry_onCreate($shiftEntry);
success(sprintf(__('%s has been subscribed to the shift.'), User_Nick_render($signup_user)));
throw_redirect(shift_link($shift));
@@ -150,14 +149,12 @@ function shift_entry_create_controller_supporter(Shift $shift, AngelType $angelt
}
if ($request->hasPostData('submit')) {
- ShiftEntry_create([
- 'SID' => $shift->id,
- 'TID' => $angeltype->id,
- 'UID' => $signup_user->id,
- 'Comment' => '',
- 'freeloaded' => false,
- 'freeload_comment' => ''
- ]);
+ $shiftEntry = new ShiftEntry();
+ $shiftEntry->shift()->associate($shift);
+ $shiftEntry->angelType()->associate($angeltype);
+ $shiftEntry->user()->associate($signup_user);
+ $shiftEntry->save();
+ ShiftEntry_onCreate($shiftEntry);
success(sprintf(__('%s has been subscribed to the shift.'), User_Nick_render($signup_user)));
throw_redirect(shift_link($shift));
@@ -214,7 +211,9 @@ function shift_entry_create_controller_user(Shift $shift, AngelType $angeltype):
$signup_user = auth()->user();
$needed_angeltype = (new AngelType())->forceFill(NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype));
- $shift_entries = ShiftEntries_by_shift_and_angeltype($shift->id, $angeltype->id);
+ $shift_entries = $shift->shiftEntries()
+ ->where('angel_type_id', $angeltype->id)
+ ->get();
$shift_signup_state = Shift_signup_allowed(
$signup_user,
$shift,
@@ -232,14 +231,14 @@ function shift_entry_create_controller_user(Shift $shift, AngelType $angeltype):
$comment = '';
if ($request->hasPostData('submit')) {
$comment = strip_request_item_nl('comment');
- ShiftEntry_create([
- 'SID' => $shift->id,
- 'TID' => $angeltype->id,
- 'UID' => $signup_user->id,
- 'Comment' => $comment,
- 'freeloaded' => false,
- 'freeload_comment' => ''
- ]);
+
+ $shiftEntry = new ShiftEntry();
+ $shiftEntry->shift()->associate($shift);
+ $shiftEntry->angelType()->associate($angeltype);
+ $shiftEntry->user()->associate($signup_user);
+ $shiftEntry->user_comment = $comment;
+ $shiftEntry->save();
+ ShiftEntry_onCreate($shiftEntry);
if (
!$angeltype->restricted
@@ -299,7 +298,7 @@ function shift_entry_create_link_admin(Shift $shift, $params = [])
/**
* Load a shift entry from get parameter shift_entry_id.
*
- * @return array
+ * @return ShiftEntry
*/
function shift_entry_load()
{
@@ -308,11 +307,7 @@ function shift_entry_load()
if (!$request->has('shift_entry_id') || !test_request_int('shift_entry_id')) {
throw_redirect(page_link_to('user_shifts'));
}
- $shiftEntry = ShiftEntry($request->input('shift_entry_id'));
- if (empty($shiftEntry)) {
- error(__('Shift entry not found.'));
- throw_redirect(page_link_to('user_shifts'));
- }
+ $shiftEntry = ShiftEntry::findOrFail($request->input('shift_entry_id'));
return $shiftEntry;
}
@@ -328,9 +323,9 @@ function shift_entry_delete_controller()
$request = request();
$shiftEntry = shift_entry_load();
- $shift = Shift($shiftEntry['SID']);
- $angeltype = AngelType::find($shiftEntry['TID']);
- $signout_user = User::find($shiftEntry['UID']);
+ $shift = Shift($shiftEntry->shift);
+ $angeltype = $shiftEntry->angelType;
+ $signout_user = $shiftEntry->user;
if (!Shift_signout_allowed($shift, $angeltype, $signout_user->id)) {
error(__(
'You are not allowed to remove this shift entry. If necessary, ask your supporter or heaven to do so.'
@@ -339,7 +334,8 @@ function shift_entry_delete_controller()
}
if ($request->hasPostData('delete')) {
- ShiftEntry_delete($shiftEntry);
+ $shiftEntry->delete();
+ ShiftEntry_onDelete($shiftEntry);
success(__('Shift entry removed.'));
throw_redirect(shift_link($shift));
}
@@ -347,7 +343,7 @@ function shift_entry_delete_controller()
if ($user->id == $signout_user->id) {
return [
ShiftEntry_delete_title(),
- ShiftEntry_delete_view($shift, $angeltype, $signout_user->id)
+ ShiftEntry_delete_view($shift, $angeltype, $signout_user)
];
}
@@ -360,8 +356,8 @@ function shift_entry_delete_controller()
/**
* Link to delete a shift entry.
*
- * @param array|Shift $shiftEntry
- * @param array $params
+ * @param Shift|ShiftEntry $shiftEntry
+ * @param array $params
* @return string URL
*/
function shift_entry_delete_link($shiftEntry, $params = [])
diff --git a/includes/controller/shifts_controller.php b/includes/controller/shifts_controller.php
index df582ff6..bbaf2d23 100644
--- a/includes/controller/shifts_controller.php
+++ b/includes/controller/shifts_controller.php
@@ -6,7 +6,6 @@ use Engelsystem\Models\AngelType;
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;
@@ -159,7 +158,6 @@ function shift_edit_controller()
$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();
@@ -244,24 +242,23 @@ function shift_delete_controller()
// Schicht löschen bestätigt
if ($request->hasPostData('delete')) {
- foreach ($shift->shiftEntry as $entry) {
- $type = AngelType::find($entry['TID']);
+ foreach ($shift->shiftEntries as $entry) {
event('shift.entry.deleting', [
- 'user' => User::find($entry['user_id']),
+ 'user' => $entry->user,
'start' => $shift->start,
'end' => $shift->end,
'name' => $shift->shiftType->name,
'title' => $shift->title,
- 'type' => $type->name,
+ 'type' => $entry->angelType->name,
'room' => $shift->room,
- 'freeloaded' => (bool) $entry['freeloaded'],
+ 'freeloaded' => $entry->freeloaded,
]);
}
$shift->delete();
engelsystem_log(
- 'Deleted shift ' . $shift->title . ': ' . $shift->shiftType->name
+ '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')
);
@@ -318,7 +315,9 @@ function shift_controller()
continue;
}
- $shift_entries = ShiftEntries_by_shift_and_angeltype($shift->id, $angeltype->id);
+ $shift_entries = $shift->shiftEntries()
+ ->where('angel_type_id', $angeltype->id)
+ ->get();
$needed_angeltype = (new AngelType())->forceFill($needed_angeltype);
$angeltype_signup_state = Shift_signup_allowed(
@@ -351,8 +350,8 @@ function shifts_controller()
}
return match ($request->input('action')) {
- 'view' => shift_controller(),
- 'next' => shift_next_controller(), // throws redirect
+ 'view' => shift_controller(),
+ 'next' => shift_next_controller(), // throws redirect
default => throw_redirect(page_link_to('/')),
};
}
@@ -368,8 +367,8 @@ function shift_next_controller()
$upcoming_shifts = ShiftEntries_upcoming_for_user(auth()->user());
- if (!empty($upcoming_shifts)) {
- throw_redirect(shift_link($upcoming_shifts[0]));
+ if (!$upcoming_shifts->isEmpty()) {
+ throw_redirect(shift_link($upcoming_shifts[0]->shift));
}
throw_redirect(page_link_to('user_shifts'));
@@ -406,41 +405,41 @@ function shifts_json_export_controller()
// See engelsystem-base/src/main/kotlin/info/metadude/kotlin/library/engelsystem/models/Shift.kt
$data = [
// Name of the shift (type)
- 'name' => $shift->shiftType->name,
+ 'name' => $shift->shiftType->name,
// Shift / Talk title
- 'title' => $shift->title,
+ 'title' => $shift->title,
// Shift description
- 'description' => $shift->description,
+ 'description' => $shift->description,
// Users comment
- 'Comment' => $shift->Comment,
+ 'Comment' => $shift->user_comment,
// Shift id
- 'SID' => $shift->id,
+ 'SID' => $shift->id,
// Shift type id
- 'shifttype_id' => $shift->shift_type_id,
+ 'shifttype_id' => $shift->shift_type_id,
// Talk URL
- 'URL' => $shift->url,
+ 'URL' => $shift->url,
// Room name
- 'Name' => $shift->room->name,
+ 'Name' => $shift->room->name,
// Location map url
- 'map_url' => $shift->room->map_url,
+ 'map_url' => $shift->room->map_url,
// Start timestamp
/** @deprecated start_date should be used */
- 'start' => $shift->start->timestamp,
+ 'start' => $shift->start->timestamp,
// Start date
- 'start_date' => $shift->start->toRfc3339String(),
+ 'start_date' => $shift->start->toRfc3339String(),
// End timestamp
/** @deprecated end_date should be used */
- 'end' => $shift->end->timestamp,
+ 'end' => $shift->end->timestamp,
// End date
- 'end_date' => $shift->end->toRfc3339String(),
+ 'end_date' => $shift->end->toRfc3339String(),
// Timezone offset like "+01:00"
/** @deprecated should be retrieved from start_date or end_date */
- 'timezone' => $timeZone->toOffsetName(),
+ 'timezone' => $timeZone->toOffsetName(),
// The events timezone like "Europe/Berlin"
'event_timezone' => $timeZone->getName(),
];
diff --git a/includes/controller/users_controller.php b/includes/controller/users_controller.php
index 7037105c..ee88475f 100644
--- a/includes/controller/users_controller.php
+++ b/includes/controller/users_controller.php
@@ -1,6 +1,7 @@
needed_angeltypes = Db::select(
'
SELECT DISTINCT `angel_types`.*
- FROM `ShiftEntry`
- JOIN `angel_types` ON `ShiftEntry`.`TID`=`angel_types`.`id`
- WHERE `ShiftEntry`.`SID` = ?
+ FROM `shift_entries`
+ JOIN `angel_types` ON `shift_entries`.`angel_type_id`=`angel_types`.`id`
+ WHERE `shift_entries`.`shift_id` = ?
ORDER BY `angel_types`.`name`
',
[$shift->id]
@@ -220,11 +221,11 @@ function user_controller()
foreach ($neededAngeltypes as &$needed_angeltype) {
$needed_angeltype['users'] = Db::select(
'
- SELECT `ShiftEntry`.`freeloaded`, `users`.*
- FROM `ShiftEntry`
- JOIN `users` ON `ShiftEntry`.`UID`=`users`.`id`
- WHERE `ShiftEntry`.`SID` = ?
- AND `ShiftEntry`.`TID` = ?
+ SELECT `shift_entries`.`freeloaded`, `users`.*
+ FROM `shift_entries`
+ JOIN `users` ON `shift_entries`.`user_id`=`users`.`id`
+ WHERE `shift_entries`.`shift_id` = ?
+ AND `shift_entries`.`angel_type_id` = ?
',
[$shift->id, $needed_angeltype['id']]
);
@@ -247,7 +248,7 @@ function user_controller()
User_view(
$user_source,
auth()->can('admin_user'),
- User_is_freeloader($user_source),
+ $user_source->isFreeloader(),
$user_source->userAngelTypes,
$user_source->groups,
$shifts,
@@ -300,7 +301,12 @@ function users_list_controller()
->orderBy('name')
->get();
foreach ($users as $user) {
- $user->setAttribute('freeloads', count(ShiftEntries_freeloaded_by_user($user->id)));
+ $user->setAttribute(
+ 'freeloads',
+ $user->shiftEntries()
+ ->where('freeloaded', true)
+ ->count()
+ );
}
$users = $users->sortBy(function (User $user) use ($order_by) {
@@ -321,7 +327,7 @@ function users_list_controller()
State::whereArrived(true)->count(),
State::whereActive(true)->count(),
State::whereForceActive(true)->count(),
- ShiftEntries_freeloaded_count(),
+ ShiftEntry::whereFreeloaded(true)->count(),
State::whereGotShirt(true)->count(),
State::query()->sum('got_voucher')
)
@@ -360,6 +366,7 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
$shift_entries_source = ShiftEntries_by_ShiftsFilter($shiftsFilter);
$needed_angeltypes = [];
+ /** @var ShiftEntry[][] $shift_entries */
$shift_entries = [];
foreach ($shifts as $shift) {
$needed_angeltypes[$shift->id] = [];
@@ -367,8 +374,8 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
}
foreach ($shift_entries_source as $shift_entry) {
- if (isset($shift_entries[$shift_entry['SID']])) {
- $shift_entries[$shift_entry['SID']][] = $shift_entry;
+ if (isset($shift_entries[$shift_entry->shift_id])) {
+ $shift_entries[$shift_entry->shift_id][] = $shift_entry;
}
}
@@ -403,8 +410,8 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
foreach ($shift_entries[$shift->id] as $shift_entry) {
if (
- $needed_angeltype['angel_type_id'] == $shift_entry['TID']
- && $shift_entry['freeloaded'] == 0
+ $needed_angeltype['angel_type_id'] == $shift_entry->angel_type_id
+ && !$shift_entry->freeloaded
) {
$taken++;
}
diff --git a/includes/mailer/shifts_mailer.php b/includes/mailer/shifts_mailer.php
index ef0976ba..c1eee921 100644
--- a/includes/mailer/shifts_mailer.php
+++ b/includes/mailer/shifts_mailer.php
@@ -1,11 +1,16 @@
id);
+ /** @var ShiftEntry[]|Collection $shiftEntries */
+ $shiftEntries = $old_shift->shiftEntries()
+ ->with(['user', 'user.settings'])
+ ->get();
$old_room = $old_shift->room;
$new_room = $new_shift->room;
@@ -65,8 +70,8 @@ function mail_shift_change(Shift $old_shift, Shift $new_shift)
$message .= $new_room->name . "\n\n";
$message .= url('/shifts', ['action' => 'view', 'shift_id' => $new_shift->id]) . "\n";
- foreach ($users as $user) {
- $user = (new User())->forceFill($user);
+ foreach ($shiftEntries as $shiftEntry) {
+ $user = $shiftEntry->user;
if ($user->settings->email_shiftinfo) {
engelsystem_email_to_user(
$user,
diff --git a/includes/model/NeededAngelTypes_model.php b/includes/model/NeededAngelTypes_model.php
index 9b6b1ab9..c2d0c9b6 100644
--- a/includes/model/NeededAngelTypes_model.php
+++ b/includes/model/NeededAngelTypes_model.php
@@ -1,6 +1,8 @@
where('shift_id', $shiftId)
+ ->get();
$needed_angeltypes = [];
foreach ($needed_angeltypes_source as $angeltype) {
$angeltype['shift_entries'] = [];
$angeltype['taken'] = 0;
foreach ($shift_entries as $shift_entry) {
- if ($shift_entry['TID'] == $angeltype['angel_type_id'] && $shift_entry['freeloaded'] == 0) {
+ if ($shift_entry->angel_type_id == $angeltype['angel_type_id'] && !$shift_entry->freeloaded) {
$angeltype['taken']++;
$angeltype['shift_entries'][] = $shift_entry;
}
diff --git a/includes/model/ShiftEntry_model.php b/includes/model/ShiftEntry_model.php
index 1323603c..21ec0921 100644
--- a/includes/model/ShiftEntry_model.php
+++ b/includes/model/ShiftEntry_model.php
@@ -1,153 +1,40 @@
shiftType;
- $room = $shift->room;
- $angeltype = AngelType::find($shift_entry['TID']);
- $result = Db::insert(
- '
- INSERT INTO `ShiftEntry` (
- `SID`,
- `TID`,
- `UID`,
- `Comment`,
- `freeload_comment`,
- `freeloaded`
- )
- VALUES(?, ?, ?, ?, ?, ?)
- ',
- [
- $shift_entry['SID'],
- $shift_entry['TID'],
- $shift_entry['UID'],
- $shift_entry['Comment'],
- $shift_entry['freeload_comment'],
- (int) $shift_entry['freeloaded'],
- ]
- );
+ $shift = $shiftEntry->shift;
engelsystem_log(
- 'User ' . User_Nick_render($user, true)
- . ' signed up for shift ' . $shift->title
- . ' (' . $shifttype->name . ')'
- . ' at ' . $room->name
+ 'User ' . User_Nick_render($shiftEntry->user, true)
+ . ' signed up for shift ' . $shiftEntry->shift->title
+ . ' (' . $shift->shiftType->name . ')'
+ . ' at ' . $shift->room->name
. ' from ' . $shift->start->format('Y-m-d H:i')
. ' to ' . $shift->end->format('Y-m-d H:i')
- . ' as ' . $angeltype->name
+ . ' as ' . $shiftEntry->angelType->name
);
- mail_shift_assign($user, $shift);
-
- return $result;
-}
-
-/**
- * Update a shift entry.
- *
- * @param array $shift_entry
- */
-function ShiftEntry_update($shift_entry)
-{
- Db::update(
- '
- UPDATE `ShiftEntry`
- SET
- `Comment` = ?,
- `freeload_comment` = ?,
- `freeloaded` = ?
- WHERE `id` = ?
- ',
- [
- $shift_entry['Comment'],
- $shift_entry['freeload_comment'],
- (int) $shift_entry['freeloaded'],
- $shift_entry['id']
- ]
- );
-}
-
-/**
- * Get a shift entry.
- *
- * @param int $shift_entry_id
- * @return array|null
- */
-function ShiftEntry($shift_entry_id)
-{
- $shiftEntry = Db::selectOne('SELECT * FROM `ShiftEntry` WHERE `id` = ?', [$shift_entry_id]);
-
- return empty($shiftEntry) ? null : $shiftEntry;
+ mail_shift_assign($shiftEntry->user, $shift);
}
/**
* Delete a shift entry.
*
- * @param array $shiftEntry
+ * @param ShiftEntry $shiftEntry
*/
-function ShiftEntry_delete($shiftEntry)
+function ShiftEntry_onDelete(ShiftEntry $shiftEntry)
{
- Db::delete('DELETE FROM `ShiftEntry` WHERE `id` = ?', [$shiftEntry['id']]);
-
- $signout_user = User::find($shiftEntry['UID']);
- $shift = Shift($shiftEntry['SID']);
+ $signout_user = $shiftEntry->user;
+ $shift = Shift($shiftEntry->shift);
$shifttype = $shift->shiftType;
$room = $shift->room;
- $angeltype = AngelType::find($shiftEntry['TID']);
+ $angeltype = $shiftEntry->angelType;
engelsystem_log(
'Shift signout: ' . User_Nick_render($signout_user, true)
@@ -159,100 +46,44 @@ function ShiftEntry_delete($shiftEntry)
. ' as ' . $angeltype->name
);
- mail_shift_removed(User::find($shiftEntry['UID']), $shift);
+ mail_shift_removed($signout_user, $shift);
}
/**
* Returns next (or current) shifts of given user.
*
* @param User $user
- * @return array
+ * @return ShiftEntry[]|Collection
*/
function ShiftEntries_upcoming_for_user(User $user)
{
- return Db::select(
- '
- SELECT *, shifts.id as shift_id
- FROM `ShiftEntry`
- JOIN `shifts` ON (`shifts`.`id` = `ShiftEntry`.`SID`)
- JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
- WHERE `ShiftEntry`.`UID` = ?
- AND `shifts`.`end` > NOW()
- ORDER BY `shifts`.`end`
- ',
- [
- $user->id
- ]
- );
+ return $user->shiftEntries()
+ ->with(['shift', 'shift.shiftType'])
+ ->join('shifts', 'shift_entries.shift_id', 'shifts.id')
+ ->where('shifts.end', '>', Carbon::now())
+ ->orderBy('shifts.end')
+ ->get();
}
/**
* Returns shifts completed by the given user.
*
- * @param User $user
+ * @param User $user
* @param Carbon|null $sinceTime
- * @return array
+ * @return ShiftEntry[]|Collection
*/
function ShiftEntries_finished_by_user(User $user, Carbon $sinceTime = null)
{
- return Db::select(
- '
- SELECT *
- FROM `ShiftEntry`
- JOIN `shifts` ON (`shifts`.`id` = `ShiftEntry`.`SID`)
- JOIN `shift_types` ON `shift_types`.`id` = `shifts`.`shift_type_id`
- WHERE `ShiftEntry`.`UID` = ?
- AND `shifts`.`end` < NOW()
- AND `ShiftEntry`.`freeloaded` = 0
- ' . ($sinceTime ? 'AND shifts.start >= "' . $sinceTime->toString() . '"' : '') . '
- ORDER BY `shifts`.`end` desc
- ',
- [
- $user->id,
- ]
- );
-}
+ $query = $user->shiftEntries()
+ ->with(['shift', 'shift.shiftType'])
+ ->join('shifts', 'shift_entries.shift_id', 'shifts.id')
+ ->where('shifts.end', '<', Carbon::now())
+ ->where('freeloaded', false)
+ ->orderByDesc('shifts.end');
-/**
- * Returns all shift entries in given shift for given angeltype.
- *
- * @param int $shift_id
- * @param int $angeltype_id
- * @return array
- */
-function ShiftEntries_by_shift_and_angeltype($shift_id, $angeltype_id)
-{
- return Db::select(
- '
- SELECT *
- FROM `ShiftEntry`
- WHERE `SID` = ?
- AND `TID` = ?
- ',
- [
- $shift_id,
- $angeltype_id,
- ]
- );
-}
+ if ($sinceTime) {
+ $query = $query->where('shifts.start', '>=', $sinceTime);
+ }
-/**
- * Returns all freeloaded shifts for given user.
- *
- * @param int $userId
- * @return array
- */
-function ShiftEntries_freeloaded_by_user($userId)
-{
- return Db::select(
- '
- SELECT *
- FROM `ShiftEntry`
- WHERE `freeloaded` = 1
- AND `UID` = ?
- ',
- [
- $userId
- ]
- );
+ return $query->get();
}
diff --git a/includes/model/Shifts_model.php b/includes/model/Shifts_model.php
index 185f3633..5bdcd136 100644
--- a/includes/model/Shifts_model.php
+++ b/includes/model/Shifts_model.php
@@ -4,11 +4,13 @@ use Engelsystem\Database\Db;
use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\Shift;
+use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
use Engelsystem\Models\UserAngelType;
use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftSignupState;
-use Illuminate\Support\Collection;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Collection as SupportCollection;
/**
* @param AngelType $angeltype
@@ -57,7 +59,7 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
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`.`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()) . ')' : '') . ')
+ > (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND shift_entries.`freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
@@ -68,7 +70,7 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
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`.`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()) . ')' : '') . ')
+ > (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND `freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND NOT s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
) AS `tmp`
@@ -246,41 +248,21 @@ function NeededAngeltype_by_Shift_and_Angeltype(Shift $shift, AngelType $angelty
/**
* @param ShiftsFilter $shiftsFilter
- * @return array[]
+ * @return ShiftEntry[]|Collection
*/
function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{
- $sql = sprintf(
- '
- SELECT
- users.*,
- `ShiftEntry`.`UID`,
- `ShiftEntry`.`TID`,
- `ShiftEntry`.`SID`,
- `ShiftEntry`.`Comment`,
- `ShiftEntry`.`freeloaded`
- FROM `shifts`
- JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`shifts`.`id`
- JOIN `users` ON `ShiftEntry`.`UID`=`users`.`id`
- WHERE `shifts`.`room_id` IN (%s)
- AND `start` BETWEEN ? AND ?
- ORDER BY `shifts`.`start`
- ',
- implode(',', $shiftsFilter->getRooms())
- );
- return Db::select(
- $sql,
- [
- $shiftsFilter->getStart(),
- $shiftsFilter->getEnd(),
- ]
- );
+ return ShiftEntry::with('user')
+ ->join('shifts', 'shifts.id', 'shift_entries.shift_id')
+ ->whereIn('shifts.room_id', $shiftsFilter->getRooms())
+ ->whereBetween('start', [$shiftsFilter->getStart(), $shiftsFilter->getEnd()])
+ ->get();
}
/**
* Check if a shift collides with other shifts (in time).
*
- * @param Shift $shift
+ * @param Shift $shift
* @param Shift[]|Collection $shifts
* @return bool
*/
@@ -290,8 +272,8 @@ function Shift_collides(Shift $shift, $shifts)
if ($shift->id != $other_shift->id) {
if (
!(
- $shift->start->timestamp >= $other_shift->end->timestamp
- || $shift->end->timestamp <= $other_shift->start->timestamp
+ $shift->start->timestamp >= $other_shift->end->timestamp
+ || $shift->end->timestamp <= $other_shift->start->timestamp
)
) {
return true;
@@ -304,15 +286,15 @@ function Shift_collides(Shift $shift, $shifts)
/**
* Returns the number of needed angels/free shift entries for an angeltype.
*
- * @param AngelType $needed_angeltype
- * @param array[] $shift_entries
+ * @param AngelType $needed_angeltype
+ * @param ShiftEntry[]|Collection $shift_entries
* @return int
*/
function Shift_free_entries(AngelType $needed_angeltype, $shift_entries)
{
$taken = 0;
foreach ($shift_entries as $shift_entry) {
- if ($shift_entry['freeloaded'] == 0) {
+ if (!$shift_entry->freeloaded) {
$taken++;
}
}
@@ -330,7 +312,7 @@ function Shift_free_entries(AngelType $needed_angeltype, $shift_entries)
* @param array|null $user_angeltype
* @param SHift[]|Collection|null $user_shifts List of the users shifts
* @param AngelType $needed_angeltype
- * @param array[] $shift_entries
+ * @param ShiftEntry[]|Collection $shift_entries
* @return ShiftSignupState
*/
function Shift_signup_allowed_angel(
@@ -410,8 +392,8 @@ function Shift_signup_allowed_angel(
/**
* Check if an angeltype supporter can sign up a user to a shift.
*
- * @param AngelType $needed_angeltype
- * @param array[] $shift_entries
+ * @param AngelType $needed_angeltype
+ * @param ShiftEntry[]|Collection $shift_entries
* @return ShiftSignupState
*/
function Shift_signup_allowed_angeltype_supporter(AngelType $needed_angeltype, $shift_entries)
@@ -427,8 +409,8 @@ function Shift_signup_allowed_angeltype_supporter(AngelType $needed_angeltype, $
/**
* Check if an admin can sign up a user to a shift.
*
- * @param AngelType $needed_angeltype
- * @param array[] $shift_entries
+ * @param AngelType $needed_angeltype
+ * @param ShiftEntry[]|Collection $shift_entries
* @return ShiftSignupState
*/
function Shift_signup_allowed_admin(AngelType $needed_angeltype, $shift_entries)
@@ -484,7 +466,7 @@ function Shift_signout_allowed(Shift $shift, AngelType $angeltype, $signout_user
* @param array|null $user_angeltype
* @param Shift[]|Collection|null $user_shifts List of the users shifts
* @param AngelType $needed_angeltype
- * @param array[] $shift_entries
+ * @param ShiftEntry[]|Collection $shift_entries
* @return ShiftSignupState
*/
function Shift_signup_allowed(
@@ -522,10 +504,10 @@ function Shift_signup_allowed(
* Return users shifts.
*
* @param int $userId
- * @param bool $include_freeload_comments
- * @return Collection|Shift[]
+ * @param bool $include_freeloaded_comments
+ * @return SupportCollection|Shift[]
*/
-function Shifts_by_user($userId, $include_freeload_comments = false)
+function Shifts_by_user($userId, $include_freeloaded_comments = false)
{
$shiftsData = Db::select(
'
@@ -534,19 +516,19 @@ function Shifts_by_user($userId, $include_freeload_comments = false)
`rooms`.name AS Name,
`shift_types`.`id` AS `shifttype_id`,
`shift_types`.`name`,
- `ShiftEntry`.`id` as shift_entry_id,
- `ShiftEntry`.`SID`,
- `ShiftEntry`.`TID`,
- `ShiftEntry`.`UID`,
- `ShiftEntry`.`freeloaded`,
- `ShiftEntry`.`Comment`,
- ' . ($include_freeload_comments ? '`ShiftEntry`.`freeload_comment`, ' : '') . '
+ `shift_entries`.`id` as shift_entry_id,
+ `shift_entries`.`shift_id`,
+ `shift_entries`.`angel_type_id`,
+ `shift_entries`.`user_id`,
+ `shift_entries`.`freeloaded`,
+ `shift_entries`.`user_comment`,
+ ' . ($include_freeloaded_comments ? '`shift_entries`.`freeloaded_comment`, ' : '') . '
`shifts`.*
- FROM `ShiftEntry`
- JOIN `shifts` ON (`ShiftEntry`.`SID` = `shifts`.`id`)
+ FROM `shift_entries`
+ JOIN `shifts` ON (`shift_entries`.`shift_id` = `shifts`.`id`)
JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`)
JOIN `rooms` ON (`shifts`.`room_id` = `rooms`.`id`)
- WHERE ShiftEntry.`UID` = ?
+ WHERE shift_entries.`user_id` = ?
ORDER BY `start`
',
[
@@ -578,22 +560,14 @@ function Shift($shift)
return null;
}
- $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]);
-
$neededAngels = [];
$angelTypes = NeededAngelTypes_by_shift($shift->id);
foreach ($angelTypes as $type) {
$neededAngels[] = [
- 'TID' => $type['angel_type_id'],
- 'count' => $type['count'],
- 'restricted' => $type['restricted'],
- 'taken' => $type['taken']
+ 'angel_type_id' => $type['angel_type_id'],
+ 'count' => $type['count'],
+ 'restricted' => $type['restricted'],
+ 'taken' => $type['taken']
];
}
$shift->neededAngels = $neededAngels;
diff --git a/includes/model/Stats.php b/includes/model/Stats.php
index ec20725d..04168c64 100644
--- a/includes/model/Stats.php
+++ b/includes/model/Stats.php
@@ -16,10 +16,10 @@ function stats_currently_working(ShiftsFilter $filter = null)
'
SELECT SUM((
SELECT COUNT(*)
- FROM `ShiftEntry`
- WHERE `ShiftEntry`.`SID`=`shifts`.`id`
+ FROM `shift_entries`
+ WHERE `shift_entries`.`shift_id`=`shifts`.`id`
AND `freeloaded`=0
- ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
+ ' . ($filter ? 'AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
)) AS `count`
FROM `shifts`
WHERE (`end` >= NOW() AND `start` <= NOW())
@@ -89,12 +89,12 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
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`
+ SELECT COUNT(*) FROM `shift_entries`
+ JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
- AND `ShiftEntry`.`SID`=`shifts`.`id`
+ AND `shift_entries`.`shift_id`=`shifts`.`id`
AND `freeloaded`=0
- ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
+ ' . ($filter ? 'AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
)
)
AS `count`
@@ -116,12 +116,13 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
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`
+ SELECT COUNT(*)
+ FROM `shift_entries`
+ JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
- AND `ShiftEntry`.`SID`=`shifts`.`id`
+ AND `shift_entries`.`shift_id`=`shifts`.`id`
AND `freeloaded`=0
- ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
+ ' . ($filter ? 'AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
)
)
AS `count`
@@ -168,12 +169,12 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
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`
+ SELECT COUNT(*) FROM `shift_entries`
+ JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
- AND `ShiftEntry`.`SID`=`shifts`.`id`
- AND `freeloaded`=0
- ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
+ AND `shift_entries`.`shift_id`=`shifts`.`id`
+ AND shift_entries.`freeloaded`=0
+ ' . ($filter ? 'AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
)
)
AS `count`
@@ -195,12 +196,12 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
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`
+ SELECT COUNT(*) FROM `shift_entries`
+ JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
- AND `ShiftEntry`.`SID`=`shifts`.`id`
+ AND `shift_entries`.`shift_id`=`shifts`.`id`
AND `freeloaded`=0
- ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
+ ' . ($filter ? 'AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
)
)
AS `count`
diff --git a/includes/model/User_model.php b/includes/model/User_model.php
index 1c500fb7..fd907a6b 100644
--- a/includes/model/User_model.php
+++ b/includes/model/User_model.php
@@ -25,8 +25,8 @@ function User_tshirt_score($userId)
$shift_sum_formula = User_get_shifts_sum_query();
$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`.`id`
+ FROM `users` LEFT JOIN `shift_entries` ON `users`.`id` = `shift_entries`.`user_id`
+ LEFT JOIN `shifts` ON `shift_entries`.`shift_id` = `shifts`.`id`
WHERE `users`.`id` = ?
AND `shifts`.`end` < NOW()
GROUP BY `users`.`id`
@@ -45,17 +45,6 @@ function User_tshirt_score($userId)
return $result_shifts['tshirt_score'] + $worklogHours;
}
-/**
- * Returns true if user is freeloader
- *
- * @param User $user
- * @return bool
- */
-function User_is_freeloader($user)
-{
- return count(ShiftEntries_freeloaded_by_user($user->id)) >= config('max_freeloadable_shifts');
-}
-
/**
* Returns all users that are not member of given angeltype.
*
@@ -196,15 +185,15 @@ 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, $start);
+ $shiftEntries = ShiftEntries_finished_by_user($user, $start);
$worklog = UserWorkLogsForUser($user->id, $start);
$shifts_done =
- count($shifts)
+ count($shiftEntries)
+ $worklog->count();
$shiftsTime = 0;
- foreach ($shifts as $shift) {
- $shiftsTime += (Carbon::make($shift['end'])->timestamp - Carbon::make($shift['start'])->timestamp) / 60 / 60;
+ foreach ($shiftEntries as $shiftEntry) {
+ $shiftsTime += ($shiftEntry->shift->end->timestamp - $shiftEntry->shift->start->timestamp) / 60 / 60;
}
foreach ($worklog as $entry) {
$shiftsTime += $entry->hours;
@@ -248,7 +237,7 @@ function User_get_shifts_sum_query()
OR (HOUR(shifts.start) <= %1$d AND HOUR(shifts.end) >= %2$d)
))
* (UNIX_TIMESTAMP(shifts.end) - UNIX_TIMESTAMP(shifts.start))
- * (1 - (%3$d + 1) * `ShiftEntry`.`freeloaded`)
+ * (1 - (%3$d + 1) * `shift_entries`.`freeloaded`)
), 0)
',
$nightShifts['start'],
diff --git a/includes/pages/admin_active.php b/includes/pages/admin_active.php
index 5fed6dd7..73105b74 100644
--- a/includes/pages/admin_active.php
+++ b/includes/pages/admin_active.php
@@ -60,7 +60,7 @@ function admin_active()
sprintf(
'
users.*,
- COUNT(ShiftEntry.id) AS shift_count,
+ COUNT(shift_entries.id) AS shift_count,
(%s + (
SELECT COALESCE(SUM(`hours`) * 3600, 0)
FROM `worklogs` WHERE `user_id`=`users`.`id`
@@ -70,8 +70,8 @@ function admin_active()
$shift_sum_formula
)
)
- ->leftJoin('ShiftEntry', 'users.id', '=', 'ShiftEntry.UID')
- ->leftJoin('shifts', 'ShiftEntry.SID', '=', 'shifts.id')
+ ->leftJoin('shift_entries', 'users.id', '=', 'shift_entries.user_id')
+ ->leftJoin('shifts', 'shift_entries.shift_id', '=', 'shifts.id')
->leftJoin('users_state', 'users.id', '=', 'users_state.user_id')
->where('users_state.arrived', '=', true)
->groupBy('users.id')
@@ -152,7 +152,7 @@ function admin_active()
sprintf(
'
users.*,
- COUNT(ShiftEntry.id) AS shift_count,
+ COUNT(shift_entries.id) AS shift_count,
(%s + (
SELECT COALESCE(SUM(`hours`) * 3600, 0)
FROM `worklogs` WHERE `user_id`=`users`.`id`
@@ -162,10 +162,10 @@ function admin_active()
$shift_sum_formula
)
)
- ->leftJoin('ShiftEntry', 'users.id', '=', 'ShiftEntry.UID')
+ ->leftJoin('shift_entries', 'users.id', '=', 'shift_entries.user_id')
->leftJoin('shifts', function ($join) use ($show_all_shifts) {
/** @var JoinClause $join */
- $join->on('ShiftEntry.SID', '=', 'shifts.id');
+ $join->on('shift_entries.shift_id', '=', 'shifts.id');
if (!$show_all_shifts) {
$join->where(function ($query) {
/** @var Builder $query */
diff --git a/includes/pages/admin_free.php b/includes/pages/admin_free.php
index 0287ec1e..44388b4d 100644
--- a/includes/pages/admin_free.php
+++ b/includes/pages/admin_free.php
@@ -40,11 +40,11 @@ function admin_free()
if ($request->has('submit')) {
$query = User::with('personalData')
->select('users.*')
- ->leftJoin('ShiftEntry', 'users.id', 'ShiftEntry.UID')
+ ->leftJoin('shift_entries', 'users.id', 'shift_entries.user_id')
->leftJoin('users_state', 'users.id', 'users_state.user_id')
->leftJoin('shifts', function ($join) {
/** @var JoinClause $join */
- $join->on('ShiftEntry.SID', '=', 'shifts.id')
+ $join->on('shift_entries.shift_id', '=', 'shifts.id')
->where('shifts.start', '<', Carbon::now())
->where('shifts.end', '>', Carbon::now());
})
diff --git a/includes/pages/admin_rooms.php b/includes/pages/admin_rooms.php
index 0874d363..e52fb915 100644
--- a/includes/pages/admin_rooms.php
+++ b/includes/pages/admin_rooms.php
@@ -189,15 +189,14 @@ function admin_rooms()
$shifts = $room->shifts;
foreach ($shifts as $shift) {
$shift = Shift($shift);
- foreach ($shift->shiftEntry as $entry) {
- $type = AngelType::find($entry['TID']);
+ foreach ($shift->shiftEntries as $entry) {
event('shift.entry.deleting', [
'user' => User::find($entry['user_id']),
'start' => $shift->start,
'end' => $shift->end,
'name' => $shift->shiftType->name,
'title' => $shift->title,
- 'type' => $type->name,
+ 'type' => $entry->angelType->name,
'room' => $room,
'freeloaded' => (bool) $entry['freeloaded'],
]);
diff --git a/includes/pages/admin_shifts.php b/includes/pages/admin_shifts.php
index ba24b9dc..7cfd3000 100644
--- a/includes/pages/admin_shifts.php
+++ b/includes/pages/admin_shifts.php
@@ -563,17 +563,16 @@ function admin_shifts_history(): string
foreach ($shifts as $shift) {
$shift = Shift($shift);
- foreach ($shift->shiftEntry as $entry) {
- $type = AngelType::find($entry['TID']);
+ foreach ($shift->shiftEntries as $entry) {
event('shift.entry.deleting', [
- 'user' => User::find($entry['user_id']),
+ 'user' => $entry->user,
'start' => $shift->start,
'end' => $shift->end,
'name' => $shift->shiftType->name,
'title' => $shift->title,
- 'type' => $type->name,
+ 'type' => $entry->angelType->name,
'room' => $shift->room,
- 'freeloaded' => (bool) $entry['freeloaded'],
+ 'freeloaded' => $entry->freeloaded,
]);
}
diff --git a/includes/pages/schedule/ImportSchedule.php b/includes/pages/schedule/ImportSchedule.php
index 3538e011..c0fb4158 100644
--- a/includes/pages/schedule/ImportSchedule.php
+++ b/includes/pages/schedule/ImportSchedule.php
@@ -266,15 +266,15 @@ class ImportSchedule extends BaseController
protected function fireDeleteShiftEntryEvents(Event $event): void
{
$shiftEntries = $this->db
- ->table('ShiftEntry')
+ ->table('shift_entries')
->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'
+ 'shifts.start', 'shifts.end', 'shift_entries.user_id', 'shift_entries.freeloaded'
])
- ->join('shifts', 'shifts.id', 'ShiftEntry.SID')
+ ->join('shifts', 'shifts.id', 'shift_entries.shift_id')
->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('angel_types', 'angel_types.id', 'shift_entries.angel_type_id')
->join('shift_types', 'shift_types.id', 'shifts.shift_type_id')
->where('schedule_shift.guid', $event->getGuid())
->get();
diff --git a/includes/pages/user_ical.php b/includes/pages/user_ical.php
index 1ff7e86c..132abe76 100644
--- a/includes/pages/user_ical.php
+++ b/includes/pages/user_ical.php
@@ -60,8 +60,8 @@ function make_ical_entry_from_shift(Shift $shift)
$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";
+ if (isset($shift->user_comment)) {
+ $output .= 'DESCRIPTION:' . str_replace("\n", "\\n", $shift->user_comment) . "\r\n";
}
$output .= 'DTSTAMP:' . $shift->start->utc()->format('Ymd\THis\Z') . "\r\n";
$output .= 'DTSTART:' . $shift->start->utc()->format('Ymd\THis\Z') . "\r\n";
diff --git a/includes/pages/user_myshifts.php b/includes/pages/user_myshifts.php
index 7cd89e0f..68397f28 100644
--- a/includes/pages/user_myshifts.php
+++ b/includes/pages/user_myshifts.php
@@ -1,7 +1,6 @@
has('edit') && preg_match('/^\d+$/', $request->input('edit'))) {
$shift_entry_id = $request->input('edit');
- $shift = Db::selectOne(
- '
- SELECT
- `ShiftEntry`.`freeloaded`,
- `ShiftEntry`.`freeload_comment`,
- `ShiftEntry`.`Comment`,
- `ShiftEntry`.`UID`,
- `shift_types`.`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`.`id`)
- JOIN `shift_types` ON (`shift_types`.`id` = `shifts`.`shift_type_id`)
- WHERE `ShiftEntry`.`id`=?
- AND `UID`=?
- LIMIT 1
- ',
- [
- $shift_entry_id,
- $shifts_user->id,
- ]
- );
- if (!empty($shift)) {
- /** @var Shift $shift */
- $shift = (new Shift())->forceFill($shift);
-
- $freeloaded = $shift->freeloaded;
- $freeload_comment = $shift->freeloaded_comment;
+ /** @var ShiftEntry $shiftEntry */
+ $shiftEntry = ShiftEntry::where('id', $shift_entry_id)
+ ->where('user_id', $shifts_user->id)
+ ->with(['shift', 'shift.shiftType', 'shift.room', 'user'])
+ ->first();
+ if (!empty($shiftEntry)) {
+ $shift = $shiftEntry->shift;
+ $freeloaded = $shiftEntry->freeloaded;
+ $freeloaded_comment = $shiftEntry->freeloaded_comment;
if ($request->hasPostData('submit')) {
$valid = true;
if (auth()->can('user_shifts_admin')) {
$freeloaded = $request->has('freeloaded');
- $freeload_comment = strip_request_item_nl('freeload_comment');
- if ($freeloaded && $freeload_comment == '') {
+ $freeloaded_comment = strip_request_item_nl('freeloaded_comment');
+ if ($freeloaded && $freeloaded_comment == '') {
$valid = false;
error(__('Please enter a freeload comment!'));
}
}
- $comment = $shift->Comment;
- $user_source = User::find($shift->UID);
+ $comment = $shiftEntry->user_comment;
+ $user_source = $shiftEntry->user;
if (auth()->user()->id == $user_source->id) {
$comment = strip_request_item_nl('comment');
}
if ($valid) {
- ShiftEntry_update([
- 'id' => $shift_entry_id,
- 'Comment' => $comment,
- 'freeloaded' => $freeloaded,
- 'freeload_comment' => $freeload_comment
- ]);
+ $shiftEntry->user_comment = $comment;
+ $shiftEntry->freeloaded = $freeloaded;
+ $shiftEntry->freeloaded_comment = $freeloaded_comment;
+ $shiftEntry->save();
engelsystem_log(
'Updated ' . User_Nick_render($user_source, true) . '\'s shift '
@@ -110,7 +87,7 @@ function user_myshifts()
. ' 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')
+ . '. Freeloaded: ' . ($freeloaded ? 'YES Comment: ' . $freeloaded_comment : 'NO')
);
success(__('Shift saved.'));
throw_redirect(page_link_to('users', ['action' => 'view', 'user_id' => $shifts_user->id]));
@@ -122,10 +99,10 @@ function user_myshifts()
$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,
+ $shiftEntry->angelType->name,
+ $shiftEntry->user_comment,
+ $shiftEntry->freeloaded,
+ $shiftEntry->freeloaded_comment,
auth()->can('user_shifts_admin')
);
} else {
diff --git a/includes/pages/user_shifts.php b/includes/pages/user_shifts.php
index 990d2c0c..149922dd 100644
--- a/includes/pages/user_shifts.php
+++ b/includes/pages/user_shifts.php
@@ -31,7 +31,7 @@ function user_shifts()
{
$request = request();
- if (User_is_freeloader(auth()->user())) {
+ if (auth()->user()->isFreeloader()) {
throw_redirect(page_link_to('user_myshifts'));
}
diff --git a/includes/view/ShiftCalendarRenderer.php b/includes/view/ShiftCalendarRenderer.php
index b2937398..ff14f90d 100644
--- a/includes/view/ShiftCalendarRenderer.php
+++ b/includes/view/ShiftCalendarRenderer.php
@@ -3,6 +3,8 @@
namespace Engelsystem;
use Engelsystem\Models\Shifts\Shift;
+use Engelsystem\Models\Shifts\ShiftEntry;
+use Illuminate\Support\Collection;
class ShiftCalendarRenderer
{
@@ -45,10 +47,10 @@ class ShiftCalendarRenderer
/**
* ShiftCalendarRenderer constructor.
*
- * @param Shift[] $shifts
- * @param array[] $needed_angeltypes
- * @param array[] $shift_entries
- * @param ShiftsFilter $shiftsFilter
+ * @param Shift[] $shifts
+ * @param array[] $needed_angeltypes
+ * @param ShiftEntry[][]|Collection $shift_entries
+ * @param ShiftsFilter $shiftsFilter
*/
public function __construct($shifts, private $needed_angeltypes, private $shift_entries, ShiftsFilter $shiftsFilter)
{
@@ -204,7 +206,7 @@ class ShiftCalendarRenderer
/**
* Renders a tick/block for given time
*
- * @param int $time unix timestamp
+ * @param int $time unix timestamp
* @param boolean $label Should time labels be generated?
* @return string rendered tick html
*/
diff --git a/includes/view/ShiftCalendarShiftRenderer.php b/includes/view/ShiftCalendarShiftRenderer.php
index ea8f1f63..9e5bfb1c 100644
--- a/includes/view/ShiftCalendarShiftRenderer.php
+++ b/includes/view/ShiftCalendarShiftRenderer.php
@@ -4,7 +4,9 @@ namespace Engelsystem;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\Shift;
+use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
+use Illuminate\Support\Collection;
use function theme_type;
@@ -16,10 +18,10 @@ class ShiftCalendarShiftRenderer
/**
* Renders a shift
*
- * @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
+ * @param Shift $shift The shift to render
+ * @param array[] $needed_angeltypes
+ * @param ShiftEntry[]|Collection $shift_entries
+ * @param User $user The user who is viewing the shift calendar
* @return array
*/
public function render(Shift $shift, $needed_angeltypes, $shift_entries, $user)
@@ -80,10 +82,10 @@ class ShiftCalendarShiftRenderer
}
/**
- * @param Shift $shift
- * @param array[] $needed_angeltypes
- * @param array[] $shift_entries
- * @param User $user
+ * @param Shift $shift
+ * @param array[] $needed_angeltypes
+ * @param ShiftEntry[]|Collection $shift_entries
+ * @param User $user
* @return array
*/
private function renderShiftNeededAngeltypes(Shift $shift, $needed_angeltypes, $shift_entries, $user)
@@ -93,7 +95,7 @@ class ShiftCalendarShiftRenderer
$shift_entries_filtered[$needed_angeltype['id']] = [];
}
foreach ($shift_entries as $shift_entry) {
- $shift_entries_filtered[$shift_entry['TID']][] = $shift_entry;
+ $shift_entries_filtered[$shift_entry->angel_type_id][] = $shift_entry;
}
$html = '';
@@ -144,11 +146,11 @@ class ShiftCalendarShiftRenderer
/**
* Renders a list entry containing the needed angels for an angeltype
*
- * @param Shift $shift The shift which is rendered
- * @param array[] $shift_entries
- * @param array $angeltype The angeltype, containing information about needed angeltypes
+ * @param Shift $shift The shift which is rendered
+ * @param ShiftEntry[]|Collection $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
+ * @param User $user The user who is viewing the shift calendar
* @return array
*/
private function renderShiftNeededAngeltype(Shift $shift, $shift_entries, $angeltype, $user)
@@ -156,8 +158,8 @@ class ShiftCalendarShiftRenderer
$angeltype = (new AngelType())->forceFill($angeltype);
$entry_list = [];
foreach ($shift_entries as $entry) {
- $class = $entry['freeloaded'] ? 'text-decoration-line-through' : '';
- $entry_list[] = '' . User_Nick_render($entry) . '';
+ $class = $entry->freeloaded ? 'text-decoration-line-through' : '';
+ $entry_list[] = '' . User_Nick_render($entry->user) . '';
}
$shift_signup_state = Shift_signup_allowed(
$user,
diff --git a/includes/view/ShiftEntry_view.php b/includes/view/ShiftEntry_view.php
index d84cf24c..1da3ce07 100644
--- a/includes/view/ShiftEntry_view.php
+++ b/includes/view/ShiftEntry_view.php
@@ -39,11 +39,11 @@ function ShiftEntry_delete_view_admin(Shift $shift, AngelType $angeltype, User $
*
* @param Shift $shift
* @param AngelType $angeltype
- * @param int $signoff_user_id
+ * @param User $signoff_user
*
* @return string HTML
*/
-function ShiftEntry_delete_view(Shift $shift, AngelType $angeltype, $signoff_user_id)
+function ShiftEntry_delete_view(Shift $shift, AngelType $angeltype, User $signoff_user)
{
return page_with_title(ShiftEntry_delete_title(), [
info(sprintf(
@@ -56,7 +56,7 @@ function ShiftEntry_delete_view(Shift $shift, AngelType $angeltype, $signoff_use
form([
buttons([
- button(user_link($signoff_user_id), icon('x-lg') . __('cancel')),
+ button(user_link($signoff_user->id), icon('x-lg') . __('cancel')),
form_submit('delete', icon('trash') . __('delete'), 'btn-danger', false),
]),
]),
@@ -180,7 +180,7 @@ function ShiftEntry_create_title()
* @param string $type
* @param string $comment
* @param bool $freeloaded
- * @param string $freeload_comment
+ * @param string $freeloaded_comment
* @param bool $user_admin_shifts
* @return string
*/
@@ -192,7 +192,7 @@ function ShiftEntry_edit_view(
$type,
$comment,
$freeloaded,
- $freeload_comment,
+ $freeloaded_comment,
$user_admin_shifts = false
) {
$freeload_form = [];
@@ -200,9 +200,9 @@ function ShiftEntry_edit_view(
$freeload_form = [
form_checkbox('freeloaded', __('Freeloaded'), $freeloaded),
form_textarea(
- 'freeload_comment',
+ 'freeloaded_comment',
__('Freeload comment (Only for shift coordination):'),
- $freeload_comment
+ $freeloaded_comment
)
];
}
diff --git a/includes/view/Shifts_view.php b/includes/view/Shifts_view.php
index d7b9d2ad..7da4bdc5 100644
--- a/includes/view/Shifts_view.php
+++ b/includes/view/Shifts_view.php
@@ -3,8 +3,8 @@
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\Shift;
+use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\Shifts\ShiftType;
-use Engelsystem\Models\User\User;
use Engelsystem\Models\UserAngelType;
use Engelsystem\ShiftSignupState;
use Illuminate\Support\Collection;
@@ -75,8 +75,8 @@ function Shift_editor_info_render(Shift $shift)
}
/**
- * @param Shift $shift
- * @param AngelType $angeltype
+ * @param Shift $shift
+ * @param AngelType $angeltype
* @return string
*/
function Shift_signup_button_render(Shift $shift, AngelType $angeltype)
@@ -136,16 +136,16 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
$needed_angels .= Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin);
}
- $shiftEntry = new Collection($shift->shiftEntry);
- foreach ($shiftEntry->groupBy('TID') as $angelTypes) {
+ $shiftEntry = $shift->shiftEntries;
+ foreach ($shiftEntry->groupBy('angel_type_id') as $angelTypes) {
/** @var Collection $angelTypes */
- $type = $angelTypes->first()['TID'];
- if (!$neededAngels->where('TID', $type)->first()) {
+ $type = $angelTypes->first()['angel_type_id'];
+ if (!$neededAngels->where('angel_type_id', $type)->first()) {
$needed_angels .= Shift_view_render_needed_angeltype([
- 'TID' => $type,
- 'count' => 0,
- 'restricted' => true,
- 'taken' => $angelTypes->count(),
+ 'angel_type_id' => $type,
+ 'count' => 0,
+ 'restricted' => true,
+ 'taken' => $angelTypes->count(),
], $angeltypes, $shift, $user_shift_admin);
}
}
@@ -213,7 +213,7 @@ function Shift_view(Shift $shift, ShiftType $shifttype, Room $room, $angeltypes_
*/
function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, Shift $shift, $user_shift_admin)
{
- $angeltype = $angeltypes[$needed_angeltype['TID']];
+ $angeltype = $angeltypes[$needed_angeltype['angel_type_id']];
$angeltype_supporter = auth()->user()->isAngelTypeSupporter($angeltype)
|| auth()->can('admin_user_angeltypes');
@@ -242,8 +242,8 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, Shif
);
$angels = [];
- foreach ($shift->shiftEntry as $shift_entry) {
- if ($shift_entry['TID'] == $needed_angeltype['TID']) {
+ foreach ($shift->shiftEntries as $shift_entry) {
+ if ($shift_entry->angel_type_id == $needed_angeltype['angel_type_id']) {
$angels[] = Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter, $shift);
}
}
@@ -255,30 +255,30 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, Shif
}
/**
- * @param array $shift_entry
+ * @param ShiftEntry $shift_entry
* @param bool $user_shift_admin
* @param bool $angeltype_supporter
* @param Shift $shift
* @return string
*/
-function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter, Shift $shift)
+function Shift_view_render_shift_entry(ShiftEntry $shift_entry, $user_shift_admin, $angeltype_supporter, Shift $shift)
{
- $entry = User_Nick_render(User::find($shift_entry['UID']));
- if ($shift_entry['freeloaded']) {
+ $entry = User_Nick_render($shift_entry->user);
+ if ($shift_entry->freeloaded) {
$entry = '' . $entry . '';
}
- $isUser = $shift_entry['UID'] == auth()->user()->id;
+ $isUser = $shift_entry->user_id == auth()->user()->id;
if ($user_shift_admin || $angeltype_supporter || $isUser) {
$entry .= '
' . __('Freeloaded') . ': ' . $shift->freeload_comment . '
'; + . '' . __('Freeloaded') . ': ' . $shift->freeloaded_comment . '
'; } else { $myshift['comment'] .= '' . __('Freeloaded') . '
'; } @@ -332,7 +335,8 @@ function User_view_myshift(Shift $shift, $user_source, $its_me) '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->angel_type_id]), $user_source->id)) { $myshift['actions'][] = button( shift_entry_delete_link($shift), icon('trash') . __('sign off'), @@ -517,7 +521,7 @@ function User_view( return page_with_title( ' ' . ( - (config('enable_pronoun') && $user_source->personalData->pronoun) + (config('enable_pronoun') && $user_source->personalData->pronoun) ? '' . htmlspecialchars($user_source->personalData->pronoun) . ' ' : '' ) @@ -554,7 +558,7 @@ function User_view( ), icon('valentine') . __('Vouchers') ) - : '', + : '', $admin_user_worklog_privilege ? button( url('/admin/user/' . $user_source->id . '/worklog'), icon('clock-history') . __('worklog.add') @@ -572,13 +576,13 @@ function User_view( icon('braces') . __('JSON Export') ) : '', ($its_me && ( - $auth->can('shifts_json_export') - || $auth->can('ical') - || $auth->can('atom') - )) ? button( - page_link_to('user_myshifts', ['reset' => 1]), - icon('arrow-repeat') . __('Reset API key') - ) : '' + $auth->can('shifts_json_export') + || $auth->can('ical') + || $auth->can('atom') + )) ? button( + page_link_to('user_myshifts', ['reset' => 1]), + icon('arrow-repeat') . __('Reset API key') + ) : '' ]) ]) ]), @@ -591,7 +595,7 @@ function User_view( . $user_source->contact->dect . '' ) - : '' , + : '', config('enable_mobile_show') && $user_source->contact->mobile ? $user_source->settings->mobile_show ? heading( @@ -600,15 +604,15 @@ function User_view( . $user_source->contact->mobile . '' ) - : '' - : '' , + : '' + : '', $auth->can('user_messages') ? heading( '' . icon('envelope') . '' ) - : '' , + : '', ]), User_view_state($admin_user_privilege, $freeloader, $user_source), User_angeltypes_render($user_angeltypes), @@ -794,8 +798,8 @@ function User_oauth_render(User $user) foreach ($user->oauth as $oauth) { $output[] = __( isset($config[$oauth->provider]['name']) - ? $config[$oauth->provider]['name'] - : Str::ucfirst($oauth->provider) + ? $config[$oauth->provider]['name'] + : Str::ucfirst($oauth->provider) ); } @@ -887,7 +891,7 @@ function render_user_departure_date_hint() */ function render_user_freeloader_hint() { - if (User_is_freeloader(auth()->user())) { + if (auth()->user()->isFreeloader()) { return sprintf( __('You freeloaded at least %s shifts. Shift signup is locked. Please go to heavens desk to be unlocked again.'), config('max_freeloadable_shifts') diff --git a/src/Controllers/Metrics/Stats.php b/src/Controllers/Metrics/Stats.php index 5ae326e0..9e4fbbb6 100644 --- a/src/Controllers/Metrics/Stats.php +++ b/src/Controllers/Metrics/Stats.php @@ -45,27 +45,25 @@ class Stats $query = State::whereArrived(true); if (!is_null($working)) { - // @codeCoverageIgnoreStart $query ->leftJoin('worklogs', 'worklogs.user_id', '=', 'users_state.user_id') - ->leftJoin('ShiftEntry', 'ShiftEntry.UID', '=', 'users_state.user_id') + ->leftJoin('shift_entries', 'shift_entries.user_id', '=', 'users_state.user_id') ->distinct(); $query->where(function ($query) use ($working): void { /** @var QueryBuilder $query */ if ($working) { $query - ->whereNotNull('ShiftEntry.SID') + ->whereNotNull('shift_entries.shift_id') ->orWhereNotNull('worklogs.hours'); return; } $query - ->whereNull('ShiftEntry.SID') + ->whereNull('shift_entries.shift_id') ->whereNull('worklogs.hours'); }); - // @codeCoverageIgnoreEnd } return $query->count('users_state.user_id'); @@ -104,18 +102,17 @@ class Stats * The number of currently working users * * @param bool|null $freeloaded - * @codeCoverageIgnore */ public function currentlyWorkingUsers(bool $freeloaded = null): int { $query = User::query() - ->join('ShiftEntry', 'ShiftEntry.UID', '=', 'users.id') - ->join('shifts', 'shifts.id', '=', 'ShiftEntry.SID') + ->join('shift_entries', 'shift_entries.user_id', '=', 'users.id') + ->join('shifts', 'shifts.id', '=', 'shift_entries.shift_id') ->where('shifts.start', '<=', Carbon::now()) ->where('shifts.end', '>', Carbon::now()); if (!is_null($freeloaded)) { - $query->where('ShiftEntry.freeloaded', '=', $freeloaded); + $query->where('shift_entries.freeloaded', '=', $freeloaded); } return $query->count(); @@ -202,13 +199,13 @@ class Stats * @param bool|null $done * @param bool|null $freeloaded * - * @codeCoverageIgnore + * @codeCoverageIgnore because it is only used in functions that use TIMESTAMPDIFF */ protected function workSecondsQuery(bool $done = null, bool $freeloaded = null): QueryBuilder { $query = $this - ->getQuery('ShiftEntry') - ->join('shifts', 'shifts.id', '=', 'ShiftEntry.SID'); + ->getQuery('shift_entries') + ->join('shifts', 'shifts.id', '=', 'shift_entries.shift_id'); if (!is_null($freeloaded)) { $query->where('freeloaded', '=', $freeloaded); @@ -227,13 +224,13 @@ class Stats * @param bool|null $done * @param bool|null $freeloaded * - * @codeCoverageIgnore + * @codeCoverageIgnore as TIMESTAMPDIFF is not implemented in SQLite */ public function workSeconds(bool $done = null, bool $freeloaded = null): int { $query = $this->workSecondsQuery($done, $freeloaded); - return (int) $query->sum($this->raw('end - start')); + return (int) $query->sum($this->raw('TIMESTAMPDIFF(MINUTE, start, end) * 60')); } /** @@ -242,22 +239,19 @@ class Stats * @param bool|null $done * @param bool|null $freeloaded * - * @codeCoverageIgnore + * @codeCoverageIgnore as TIMESTAMPDIFF is not implemented in SQLite */ public function workBuckets(array $buckets, bool $done = null, bool $freeloaded = null): array { return $this->getBuckets( $buckets, $this->workSecondsQuery($done, $freeloaded), - 'UID', - 'SUM(end - start)', - 'SUM(end - start)' + 'user_id', + 'SUM(TIMESTAMPDIFF(MINUTE, start, end) * 60)', + 'SUM(TIMESTAMPDIFF(MINUTE, start, end) * 60)' ); } - /** - * @codeCoverageIgnore As long as its only used for old tables - */ protected function getBuckets( array $buckets, BuilderContract $basicQuery, @@ -281,18 +275,12 @@ class Stats return $return; } - /** - * @codeCoverageIgnore - */ public function worklogSeconds(): int { return (int) Worklog::query() ->sum($this->raw('hours * 60 * 60')); } - /** - * @codeCoverageIgnore - */ public function worklogBuckets(array $buckets): array { return $this->getBuckets( diff --git a/src/Models/AngelType.php b/src/Models/AngelType.php index 085c1c15..a4543768 100644 --- a/src/Models/AngelType.php +++ b/src/Models/AngelType.php @@ -4,28 +4,31 @@ declare(strict_types=1); namespace Engelsystem\Models; +use Engelsystem\Models\Shifts\ShiftEntry; use Illuminate\Database\Eloquent\Builder; use Engelsystem\Models\User\User; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Query\Builder as QueryBuilder; /** - * @property int $id - * @property string $name - * @property string $description - * @property string $contact_name - * @property string $contact_dect - * @property string $contact_email - * @property boolean $restricted # If users need an introduction - * @property boolean $requires_driver_license # If users must have a driver license - * @property boolean $no_self_signup # Users can sign up for shifts - * @property boolean $show_on_dashboard # Show on public dashboard - * @property boolean $hide_register # Hide from registration page + * @property int $id + * @property string $name + * @property string $description + * @property string $contact_name + * @property string $contact_dect + * @property string $contact_email + * @property boolean $restricted # If users need an introduction + * @property boolean $requires_driver_license # If users must have a driver license + * @property boolean $no_self_signup # Users can sign up for shifts + * @property boolean $show_on_dashboard # Show on public dashboard + * @property boolean $hide_register # Hide from registration page * - * @property-read Collection|User[] $userAngelTypes - * @property-read UserAngelType $pivot + * @property-read UserAngelType $pivot + * @property-read Collection|ShiftEntry[] $shiftEntries + * @property-read Collection|User[] $userAngelTypes * * @method static QueryBuilder|AngelType[] whereId($value) * @method static QueryBuilder|AngelType[] whereName($value) @@ -68,6 +71,11 @@ class AngelType extends BaseModel 'hide_register' => 'boolean', ]; + public function shiftEntries(): HasMany + { + return $this->hasMany(ShiftEntry::class); + } + public function userAngelTypes(): BelongsToMany { return $this diff --git a/src/Models/Shifts/Shift.php b/src/Models/Shifts/Shift.php index 9e8af282..21cdb0ac 100644 --- a/src/Models/Shifts/Shift.php +++ b/src/Models/Shifts/Shift.php @@ -8,31 +8,34 @@ use Carbon\Carbon; use Engelsystem\Models\BaseModel; use Engelsystem\Models\Room; use Engelsystem\Models\User\User; +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\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 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 + * @property-read QueryBuilder|Schedule $schedule + * @property-read QueryBuilder|Collection|ShiftEntry[] $shiftEntries + * @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) @@ -88,6 +91,11 @@ class Shift extends BaseModel return $this->hasOneThrough(Schedule::class, ScheduleShift::class, null, 'id', null, 'schedule_id'); } + public function shiftEntries(): HasMany + { + return $this->hasMany(ShiftEntry::class); + } + public function shiftType(): BelongsTo { return $this->belongsTo(ShiftType::class); diff --git a/src/Models/Shifts/ShiftEntry.php b/src/Models/Shifts/ShiftEntry.php new file mode 100644 index 00000000..5014bce1 --- /dev/null +++ b/src/Models/Shifts/ShiftEntry.php @@ -0,0 +1,63 @@ + */ + protected $fillable = [ // phpcs:ignore + 'shift_id', + 'angel_type_id', + 'user_id', + 'user_comment', + 'freeloaded', + 'freeloaded_comment', + ]; + + /** @var array