Migrate NeededAngelType model

This commit is contained in:
Igor Scheller 2023-01-22 18:43:09 +01:00 committed by GitHub
parent 89dc85c3d5
commit 96f703bf22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 459 additions and 222 deletions

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories\Engelsystem\Models\Shifts;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Factories\Factory;
class NeededAngelTypeFactory extends Factory
{
/** @var string */
protected $model = NeededAngelType::class; // phpcs:ignore
public function definition(): array
{
$forRoom = $this->faker->boolean();
return [
'room_id' => $forRoom ? Room::factory() : null,
'shift_id' => $forRoom ? null : Shift::factory(),
'angel_type_id' => AngelType::factory(),
'count' => $this->faker->numberBetween(1, 5),
];
}
}

View File

@ -0,0 +1,108 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
use stdClass;
class CreateNeededAngelTypesTable 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('NeededAngelTypes');
$this->schema->create('needed_angel_types', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'rooms')->nullable();
$this->references($table, 'shifts')->nullable();
$this->references($table, 'angel_types');
$table->integer('count')->index();
$table->index(['room_id', 'angel_type_id']);
});
if (!$previous) {
return;
}
// Delete old entries which don't need angels
$connection
->table('NeededAngelTypes')
->where('count', 0)
->delete();
/** @var stdClass[] $records */
$records = $connection
->table('NeededAngelTypes')
->get();
foreach ($records as $record) {
$connection->table('needed_angel_types')->insert([
'id' => $record->id,
'room_id' => $record->room_id,
'shift_id' => $record->shift_id,
'angel_type_id' => $record->angel_type_id,
'count' => $record->count,
]);
}
$this->changeReferences(
'NeededAngelTypes',
'id',
'needed_angel_types',
'id'
);
$this->schema->drop('NeededAngelTypes');
}
/**
* Recreates the previous table, copies the data and drops the new one
*/
public function down(): void
{
$connection = $this->schema->getConnection();
$this->schema->create('NeededAngelTypes', function (Blueprint $table): void {
$table->increments('id');
$this->references($table, 'rooms')->nullable();
$this->references($table, 'shifts')->nullable();
$this->references($table, 'angel_types');
$table->integer('count')->index();
$table->index(['room_id', 'angel_type_id']);
});
/** @var stdClass[] $records */
$records = $connection
->table('needed_angel_types')
->get();
foreach ($records as $record) {
$connection->table('NeededAngelTypes')->insert([
'id' => $record->id,
'room_id' => $record->room_id,
'shift_id' => $record->shift_id,
'angel_type_id' => $record->angel_type_id,
'count' => $record->count,
]);
}
$this->changeReferences(
'needed_angel_types',
'id',
'NeededAngelTypes',
'id'
);
$this->schema->drop('needed_angel_types');
}
}

View File

@ -3,6 +3,7 @@
use Carbon\CarbonTimeZone;
use Engelsystem\Http\Exceptions\HttpForbidden;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType;
@ -60,7 +61,7 @@ function shift_edit_controller()
}
$shift_id = $request->input('edit_shift');
$shift = Shift(Shift::findOrFail($shift_id));
$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.'
@ -149,6 +150,8 @@ function shift_edit_controller()
}
if ($valid) {
$oldShift = Shift::find($shift->id);
$shift->shift_type_id = $shifttype_id;
$shift->title = $title;
$shift->description = $description;
@ -156,19 +159,21 @@ function shift_edit_controller()
$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->neededAngels);
$shift->save();
mail_shift_change(Shift($shift->id), $shift);
mail_shift_change($oldShift, $shift);
NeededAngelTypes_delete_by_shift($shift_id);
NeededAngelType::whereShiftId($shift_id)->delete();
$needed_angel_types_info = [];
foreach ($needed_angel_types as $type_id => $count) {
NeededAngelType_add($shift_id, $type_id, null, $count);
if ($count > 0) {
$angeltype = AngelType::find($type_id);
if (!empty($angeltype) && $count > 0) {
$neededAngelType = new NeededAngelType();
$neededAngelType->shift()->associate($shift);
$neededAngelType->angel_type_id = $type_id;
$neededAngelType->count = $count;
$neededAngelType->save();
$needed_angel_types_info[] = $angeltypes[$type_id] . ': ' . $count;
}
}

View File

@ -4,75 +4,6 @@ use Engelsystem\Database\Db;
use Engelsystem\Models\Shifts\ShiftEntry;
use Illuminate\Database\Eloquent\Collection;
/**
* Entity needed angeltypes describes how many angels of given type are needed for a shift or in a room.
*/
/**
* Insert a new needed angel type.
*
* @param int|null $shift_id The shift. Can be null, but then a room_id must be given.
* @param int $angeltype_id The angeltype
* @param int|null $room_id The room. Can be null, but then a shift_id must be given.
* @param int $count How many angels are needed?
*
* @return int|false
*/
function NeededAngelType_add($shift_id, $angeltype_id, $room_id, $count)
{
Db::insert(
'
INSERT INTO `NeededAngelTypes` ( `shift_id`, `angel_type_id`, `room_id`, `count`)
VALUES (?, ?, ?, ?)
',
[
$shift_id,
$angeltype_id,
$room_id,
$count,
]
);
return Db::getPdo()->lastInsertId();
}
/**
* Deletes all needed angel types from given shift.
*
* @param int $shift_id id of the shift
*/
function NeededAngelTypes_delete_by_shift($shift_id)
{
Db::delete('DELETE FROM `NeededAngelTypes` WHERE `shift_id` = ?', [$shift_id]);
}
/**
* Deletes all needed angel types from given room.
*
* @param int $room_id id of the room
*/
function NeededAngelTypes_delete_by_room($room_id)
{
Db::delete(
'DELETE FROM `NeededAngelTypes` WHERE `room_id` = ?',
[$room_id]
);
}
/**
* Returns all needed angeltypes by room.
*
* @param int $room_id
* @return array
*/
function NeededAngelTypes_by_room($room_id)
{
return Db::select(
'SELECT `angel_type_id`, `count` FROM `NeededAngelTypes` WHERE `room_id`=?',
[$room_id]
);
}
/**
* Returns all needed angeltypes and already taken needs.
*
@ -84,15 +15,14 @@ function NeededAngelTypes_by_shift($shiftId)
$needed_angeltypes_source = Db::select(
'
SELECT
`NeededAngelTypes`.*,
`needed_angel_types`.*,
`angel_types`.`id`,
`angel_types`.`name`,
`angel_types`.`restricted`,
`angel_types`.`no_self_signup`
FROM `NeededAngelTypes`
JOIN `angel_types` ON `angel_types`.`id` = `NeededAngelTypes`.`angel_type_id`
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id`
WHERE `shift_id` = ?
AND `count` > 0
ORDER BY `room_id` DESC',
[$shiftId]
);
@ -100,12 +30,11 @@ function NeededAngelTypes_by_shift($shiftId)
// Use settings from room
if (count($needed_angeltypes_source) == 0) {
$needed_angeltypes_source = Db::select('
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`.`room_id` = `NeededAngelTypes`.`room_id`
SELECT `needed_angel_types`.*, `angel_types`.`name`, `angel_types`.`restricted`
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id` = `needed_angel_types`.`angel_type_id`
JOIN `shifts` ON `shifts`.`room_id` = `needed_angel_types`.`room_id`
WHERE `shifts`.`id` = ?
AND `count` > 0
ORDER BY `room_id` DESC
', [$shiftId]);
}

View File

@ -20,19 +20,17 @@ function Shifts_by_angeltype(AngelType $angeltype)
{
return Db::select('
SELECT DISTINCT `shifts`.* FROM `shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `shifts`.`id`
JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id` = `shifts`.`id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `NeededAngelTypes`.`angel_type_id` = ?
AND `NeededAngelTypes`.`count` > 0
WHERE `needed_angel_types`.`angel_type_id` = ?
AND s.shift_id IS NULL
UNION
SELECT DISTINCT `shifts`.* FROM `shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id` = `shifts`.`room_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`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
WHERE `needed_angel_types`.`angel_type_id` = ?
AND NOT s.shift_id IS NULL
', [$angeltype->id, $angeltype->id]);
}
@ -58,7 +56,7 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
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`.`id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
> (SELECT COUNT(*) FROM `shift_entries` WHERE `shift_entries`.`shift_id`=`shifts`.`id` AND shift_entries.`freeloaded`=0' . ($filter ? ' AND shift_entries.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND s.shift_id IS NULL
' . ($filter ? 'AND shifts.room_id IN (' . implode(',', $filter->getRooms()) . ')' : '') . '
@ -69,7 +67,7 @@ function Shifts_free($start, $end, ShiftsFilter $filter = null)
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`.`room_id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
AND (SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
> (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()) . ')' : '') . '
@ -101,12 +99,11 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
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`
JOIN `needed_angel_types` ON `needed_angel_types`.`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
AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND s.shift_id IS NULL
UNION
@ -115,12 +112,11 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
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`
JOIN `needed_angel_types` ON `needed_angel_types`.`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
AND `needed_angel_types`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND NOT s.shift_id IS NULL
) AS tmp_shifts
@ -153,15 +149,15 @@ function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{
$sql = '
SELECT
`NeededAngelTypes`.*,
`needed_angel_types`.*,
`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`.`id`
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id`=`shifts`.`id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
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 ?
@ -170,15 +166,15 @@ function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
UNION
SELECT
`NeededAngelTypes`.*,
`needed_angel_types`.*,
`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`.`room_id`
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id`=`shifts`.`room_id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`room_id` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND shifts.`start` BETWEEN ? AND ?
@ -206,15 +202,15 @@ function NeededAngeltype_by_Shift_and_Angeltype(Shift $shift, AngelType $angelty
return Db::selectOne(
'
SELECT
`NeededAngelTypes`.*,
`needed_angel_types`.*,
`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`.`id`
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`shift_id`=`shifts`.`id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`id`=?
AND `angel_types`.`id`=?
@ -223,15 +219,15 @@ function NeededAngeltype_by_Shift_and_Angeltype(Shift $shift, AngelType $angelty
UNION
SELECT
`NeededAngelTypes`.*,
`needed_angel_types`.*,
`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`.`room_id`
JOIN `angel_types` ON `angel_types`.`id`= `NeededAngelTypes`.`angel_type_id`
JOIN `needed_angel_types` ON `needed_angel_types`.`room_id`=`shifts`.`room_id`
JOIN `angel_types` ON `angel_types`.`id`= `needed_angel_types`.`angel_type_id`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
WHERE `shifts`.`id`=?
AND `angel_types`.`id`=?

View File

@ -42,7 +42,7 @@ 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`.`id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
(SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`shift_id`=`shifts`.`id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
* TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count`
FROM `shifts`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
@ -53,7 +53,7 @@ function stats_hours_to_work(ShiftsFilter $filter = null)
UNION ALL
SELECT
(SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
(SELECT SUM(`count`) FROM `needed_angel_types` WHERE `needed_angel_types`.`room_id`=`shifts`.`room_id`' . ($filter ? ' AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ')
* TIMESTAMPDIFF(MINUTE, `shifts`.`start`, `shifts`.`end`) / 60 AS `count`
FROM `shifts`
LEFT JOIN schedule_shift AS s on shifts.id = s.shift_id
@ -82,12 +82,12 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
SELECT
GREATEST(0,
(
SELECT SUM(`count`)
FROM `NeededAngelTypes`
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
SELECT SUM(needed_angel_types.`count`)
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `NeededAngelTypes`.`shift_id`=`shifts`.`id`
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
AND `needed_angel_types`.`shift_id`=`shifts`.`id`
' . ($filter ? 'AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - (
SELECT COUNT(*) FROM `shift_entries`
JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
@ -109,12 +109,12 @@ function stats_angels_needed_three_hours(ShiftsFilter $filter = null)
SELECT
GREATEST(0,
(
SELECT SUM(`count`)
FROM `NeededAngelTypes`
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
SELECT SUM(needed_angel_types.`count`)
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
AND `needed_angel_types`.`room_id`=`shifts`.`room_id`
' . ($filter ? 'AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - (
SELECT COUNT(*)
FROM `shift_entries`
@ -162,12 +162,12 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
SELECT
GREATEST(0,
(
SELECT SUM(`count`)
FROM `NeededAngelTypes`
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
SELECT SUM(needed_angel_types.`count`)
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `NeededAngelTypes`.`shift_id`=`shifts`.`id`
' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
AND `needed_angel_types`.`shift_id`=`shifts`.`id`
' . ($filter ? 'AND needed_angel_types.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - (
SELECT COUNT(*) FROM `shift_entries`
JOIN `angel_types` ON `angel_types`.`id`=`shift_entries`.`angel_type_id`
@ -189,11 +189,11 @@ function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null)
SELECT
GREATEST(0,
(
SELECT SUM(`count`)
FROM `NeededAngelTypes`
JOIN `angel_types` ON `angel_types`.`id`=`NeededAngelTypes`.`angel_type_id`
SELECT SUM(needed_angel_types.`count`)
FROM `needed_angel_types`
JOIN `angel_types` ON `angel_types`.`id`=`needed_angel_types`.`angel_type_id`
WHERE `angel_types`.`show_on_dashboard`=TRUE
AND `NeededAngelTypes`.`room_id`=`shifts`.`room_id`
AND `needed_angel_types`.`room_id`=`shifts`.`room_id`
' . ($filter ? 'AND angel_types.id IN (' . implode(',', $filter->getTypes()) . ')' : '') . '
) - (
SELECT COUNT(*) FROM `shift_entries`

View File

@ -2,6 +2,7 @@
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\User\User;
/**
@ -70,12 +71,10 @@ function admin_rooms()
$description = $room->description;
$dect = $room->dect;
$needed_angeltypes = NeededAngelTypes_by_room($room_id);
foreach ($needed_angeltypes as $needed_angeltype) {
$angeltypes_count[$needed_angeltype['angel_type_id']] = $needed_angeltype['count'];
$angeltypes_count = NeededAngelType::whereRoomId($room_id)
->pluck('count', 'angel_type_id')
->toArray() + $angeltypes_count;
}
}
if ($request->input('show') == 'edit') {
if ($request->hasPostData('submit')) {
$valid = true;
@ -129,17 +128,20 @@ function admin_rooms()
Room_update($room_id, $name, $map_url, $description, $dect);
}
NeededAngelTypes_delete_by_room($room_id);
NeededAngelType::whereRoomId($room_id)->delete();
$needed_angeltype_info = [];
foreach ($angeltypes_count as $angeltype_id => $angeltype_count) {
$angeltype = AngelType::find($angeltype_id);
if (!empty($angeltype)) {
NeededAngelType_add(null, $angeltype_id, $room_id, $angeltype_count);
if ($angeltype_count > 0) {
if (!empty($angeltype) && $angeltype_count > 0) {
$neededAngelType = new NeededAngelType();
$neededAngelType->room_id = $room_id;
$neededAngelType->angelType()->associate($angeltype);
$neededAngelType->count = $angeltype_count;
$neededAngelType->save();
$needed_angeltype_info[] = $angeltype->name . ': ' . $angeltype_count;
}
}
}
engelsystem_log(
'Set needed angeltypes of room ' . $name

View File

@ -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\NeededAngelType;
use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType;
@ -184,18 +185,9 @@ function admin_shifts()
// Alle Eingaben in Ordnung
if ($valid) {
if ($angelmode == 'location') {
$needed_angel_types = [];
$needed_angel_types_location = Db::select(
'
SELECT `angel_type_id`, `count`
FROM `NeededAngelTypes`
WHERE `room_id`=?
',
[$rid]
);
foreach ($needed_angel_types_location as $type) {
$needed_angel_types[$type['angel_type_id']] = $type['count'];
}
$needed_angel_types = NeededAngelType::whereRoomId($rid)
->pluck('count', 'angel_type_id')
->toArray() + $needed_angel_types;
}
$shifts = [];
@ -377,7 +369,6 @@ function admin_shifts()
$shift->transaction_id = $transactionId;
$shift->createdBy()->associate(auth()->user());
$shift->save();
$shift_id = $shift->id;
engelsystem_log(
'Shift created: ' . $shifttypes[$shift->shift_type_id]
@ -391,24 +382,16 @@ function admin_shifts()
$needed_angel_types_info = [];
foreach ($session->get('admin_shifts_types', []) as $type_id => $count) {
$angel_type_source = AngelType::find($type_id);
if (!empty($angel_type_source)) {
Db::insert(
'
INSERT INTO `NeededAngelTypes` (`shift_id`, `angel_type_id`, `count`)
VALUES (?, ?, ?)
',
[
$shift_id,
$type_id,
$count
]
);
if (!empty($angel_type_source) && $count > 0) {
$neededAngelType = new NeededAngelType();
$neededAngelType->shift()->associate($shift);
$neededAngelType->angelType()->associate($angel_type_source);
$neededAngelType->count = $count;
$neededAngelType->save();
if ($count > 0) {
$needed_angel_types_info[] = $angel_type_source->name . ': ' . $count;
}
}
}
engelsystem_log('Shift needs following angel types: ' . join(', ', $needed_angel_types_info));
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Engelsystem\Models;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\ShiftEntry;
use Illuminate\Database\Eloquent\Builder;
use Engelsystem\Models\User\User;
@ -26,6 +27,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property boolean $show_on_dashboard # Show on public dashboard
* @property boolean $hide_register # Hide from registration page
*
* @property-read Collection|NeededAngelType[] $neededBy
* @property-read UserAngelType $pivot
* @property-read Collection|ShiftEntry[] $shiftEntries
* @property-read Collection|User[] $userAngelTypes
@ -71,6 +73,11 @@ class AngelType extends BaseModel
'hide_register' => 'boolean',
];
public function neededBy(): HasMany
{
return $this->hasMany(NeededAngelType::class);
}
public function shiftEntries(): HasMany
{
return $this->hasMany(ShiftEntry::class);

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Models;
use Carbon\Carbon;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -20,6 +21,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property-read Collection|NeededAngelType[] $neededAngelTypes
* @property-read Collection|Shift[] $shifts
*
* @method static QueryBuilder|Room[] whereId($value)
@ -45,6 +47,11 @@ class Room extends BaseModel
'description',
];
public function neededAngelTypes(): HasMany
{
return $this->hasMany(NeededAngelType::class);
}
public function shifts(): HasMany
{
return $this->hasMany(Shift::class);

View File

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

View File

@ -30,12 +30,13 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @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
* @property-read Collection|NeededAngelType[] $neededAngelTypes
* @property-read Schedule $schedule
* @property-read Collection|ShiftEntry[] $shiftEntries
* @property-read ShiftType $shiftType
* @property-read Room $room
* @property-read User $createdBy
* @property-read User|null $updatedBy
*
* @method static QueryBuilder|Shift[] whereId($value)
* @method static QueryBuilder|Shift[] whereTitle($value)
@ -86,6 +87,11 @@ class Shift extends BaseModel
'end',
];
public function neededAngelTypes(): HasMany
{
return $this->hasMany(NeededAngelType::class);
}
public function schedule(): HasOneThrough
{
return $this->hasOneThrough(Schedule::class, ScheduleShift::class, null, 'id', null, 'schedule_id');

View File

@ -3,6 +3,7 @@
namespace Engelsystem\Test\Unit\Models;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
use Engelsystem\Models\UserAngelType;
@ -70,9 +71,25 @@ class AngelTypeTest extends ModelTest
ShiftEntry::factory(3)->create(['angel_type_id' => $angelType->id]);
$angelType = AngelType::find(1);
$this->assertCount(3, $angelType->shiftEntries);
}
/**
* @covers \Engelsystem\Models\AngelType::neededBy
*/
public function testNeededBy(): void
{
$angelType = AngelType::create(['name' => 'test type']);
$this->assertCount(0, $angelType->neededBy);
NeededAngelType::factory(4)->create(['angel_type_id' => $angelType->id]);
$angelType = AngelType::find(1);
$this->assertCount(4, $angelType->neededBy);
}
/**
* @covers \Engelsystem\Models\AngelType::boot
*/

View File

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

View File

@ -0,0 +1,40 @@
<?php
namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Test\Unit\Models\ModelTest;
class NeededAngelTypeTest extends ModelTest
{
/**
* @covers \Engelsystem\Models\Shifts\NeededAngelType::room
* @covers \Engelsystem\Models\Shifts\NeededAngelType::shift
* @covers \Engelsystem\Models\Shifts\NeededAngelType::angelType
*/
public function testShift(): void
{
/** @var Room $room */
$room = Room::factory()->create();
/** @var Shift $shift */
$shift = Shift::factory()->create();
/** @var AngelType $angelType */
$angelType = AngelType::factory()->create();
$model = new NeededAngelType();
$model->room()->associate($room);
$model->shift()->associate($shift);
$model->angelType()->associate($angelType);
$model->count = 3;
$model->save();
$model = NeededAngelType::find(1);
$this->assertEquals($room->id, $model->room->id);
$this->assertEquals($shift->id, $model->shift->id);
$this->assertEquals($angelType->id, $model->angelType->id);
$this->assertEquals(3, $model->count);
}
}

View File

@ -6,6 +6,7 @@ namespace Engelsystem\Test\Unit\Models\Shifts;
use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\ScheduleShift;
use Engelsystem\Models\Shifts\Shift;
@ -56,6 +57,28 @@ class ShiftTest extends ModelTest
$this->assertEquals($user2->id, $model->updatedBy->id);
}
/**
* @covers \Engelsystem\Models\Shifts\Shift::neededAngelTypes
*/
public function testNeededAngelTypes(): void
{
/** @var Collection|Shift[] $shifts */
$shifts = Shift::factory(3)->create();
$this->assertCount(0, Shift::find(1)->neededAngelTypes);
(NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'room_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[0]->id, 'room_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[1]->id, 'room_id' => null]))->save();
(NeededAngelType::factory()->make(['shift_id' => $shifts[2]->id, 'room_id' => null]))->save();
$this->assertCount(2, Shift::find(1)->neededAngelTypes);
$this->assertEquals(1, Shift::find(1)->neededAngelTypes[0]->id);
$this->assertEquals(2, Shift::find(1)->neededAngelTypes[1]->id);
$this->assertEquals(3, Shift::find(2)->neededAngelTypes->first()->id);
$this->assertEquals(4, Shift::find(3)->neededAngelTypes->first()->id);
}
/**
* @covers \Engelsystem\Models\Shifts\Shift::schedule
*/