refactor shirt to goodie

This commit is contained in:
Xu 2024-04-10 18:29:12 +02:00 committed by Igor Scheller
parent 3fd8267f12
commit 0f2c7c5394
20 changed files with 171 additions and 125 deletions

View File

@ -252,12 +252,12 @@ $route->addGroup(
$route->addGroup( $route->addGroup(
'/user/{user_id:\d+}', '/user/{user_id:\d+}',
function (RouteCollector $route): void { function (RouteCollector $route): void {
// Shirts // Goodies
$route->addGroup( $route->addGroup(
'/goodie', '/goodie',
function (RouteCollector $route): void { function (RouteCollector $route): void {
$route->get('', 'Admin\\UserShirtController@editShirt'); $route->get('', 'Admin\\UserGoodieController@editGoodie');
$route->post('', 'Admin\\UserShirtController@saveShirt'); $route->post('', 'Admin\\UserGoodieController@saveGoodie');
} }
); );

View File

@ -25,7 +25,7 @@ class StateFactory extends Factory
'user_info' => $this->faker->optional(.1)->text(), 'user_info' => $this->faker->optional(.1)->text(),
'active' => $this->faker->boolean(.3), 'active' => $this->faker->boolean(.3),
'force_active' => $this->faker->boolean(.1), 'force_active' => $this->faker->boolean(.1),
'got_shirt' => $this->faker->boolean(), 'got_goodie' => $this->faker->boolean(),
'got_voucher' => $this->faker->numberBetween(0, 10), 'got_voucher' => $this->faker->numberBetween(0, 10),
]; ];
} }

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class RenameShirtToGoodie extends Migration
{
/**
* Run the migration
*/
public function up(): void
{
$this->schema->table('users_state', function (Blueprint $table): void {
$table->renameColumn('got_shirt', 'got_goodie');
});
$db = $this->schema->getConnection();
$db->table('privileges')->where('name', 'admin_active')->update([
'description' => 'Mark angels as active and if they got a goodie.',
]);
$db->table('privileges')->where('name', 'user.edit.shirt')->update([
'name' => 'user.goodie.edit',
'description' => 'Edit user goodies',
]);
}
/**
* Reverse the migration
*/
public function down(): void
{
$this->schema->table('users_state', function (Blueprint $table): void {
$table->renameColumn('got_goodie', 'got_shirt');
});
$db = $this->schema->getConnection();
$db->table('privileges')->where('name', 'admin_active')->update([
'description' => 'Mark angels as active and if they got a t-shirt.',
]);
$db->table('privileges')->where('name', 'user.goodie.edit')->update([
'name' => 'user.edit.shirt',
'description' => 'Edit user shirts',
]);
}
}

View File

@ -239,9 +239,9 @@ function user_controller()
auth()->resetApiKey($user_source); auth()->resetApiKey($user_source);
} }
$tshirt_score = sprintf('%.2f', User_tshirt_score($user_source->id)) . '&nbsp;h'; $goodie_score = sprintf('%.2f', User_goodie_score($user_source->id)) . '&nbsp;h';
if ($user_source->state->force_active && config('enable_force_active')) { if ($user_source->state->force_active && config('enable_force_active')) {
$tshirt_score = '<span title="' . $tshirt_score . '">' . __('Enough') . '</span>'; $goodie_score = '<span title="' . $goodie_score . '">' . __('Enough') . '</span>';
} }
$worklogs = $user_source->worklogs() $worklogs = $user_source->worklogs()
@ -270,8 +270,8 @@ function user_controller()
$user_source->groups, $user_source->groups,
$shifts, $shifts,
$user->id == $user_source->id, $user->id == $user_source->id,
$tshirt_score, $goodie_score,
auth()->can('user.edit.shirt'), auth()->can('user.goodie.edit'),
auth()->can('admin_user_worklog'), auth()->can('admin_user_worklog'),
$worklogs, $worklogs,
auth()->can('user.ifsg.edit') auth()->can('user.ifsg.edit')
@ -307,7 +307,7 @@ function users_list_controller()
'freeloads', 'freeloads',
'active', 'active',
'force_active', 'force_active',
'got_shirt', 'got_goodie',
'shirt_size', 'shirt_size',
'planned_arrival_date', 'planned_arrival_date',
'planned_departure_date', 'planned_departure_date',
@ -351,7 +351,7 @@ function users_list_controller()
State::whereActive(true)->count(), State::whereActive(true)->count(),
State::whereForceActive(true)->count(), State::whereForceActive(true)->count(),
ShiftEntry::whereFreeloaded(true)->count(), ShiftEntry::whereFreeloaded(true)->count(),
State::whereGotShirt(true)->count(), State::whereGotGoodie(true)->count(),
State::query()->sum('got_voucher') State::query()->sum('got_voucher')
), ),
]; ];

View File

@ -13,17 +13,17 @@ use Illuminate\Support\Collection;
*/ */
/** /**
* Returns the tshirt score (number of hours counted for tshirt). * Returns the goodie score (number of hours counted for tshirt).
* Accounts only ended shifts. * Accounts only ended shifts.
* *
* @param int $userId * @param int $userId
* @return int * @return float
*/ */
function User_tshirt_score($userId) function User_goodie_score(int $userId): float
{ {
$shift_sum_formula = User_get_shifts_sum_query(); $shift_sum_formula = User_get_shifts_sum_query();
$result_shifts = Db::selectOne(sprintf(' $result_shifts = Db::selectOne(sprintf('
SELECT ROUND((%s) / 3600, 2) AS `tshirt_score` SELECT ROUND((%s) / 3600, 2) AS `goodie_score`
FROM `users` LEFT JOIN `shift_entries` ON `users`.`id` = `shift_entries`.`user_id` FROM `users` LEFT JOIN `shift_entries` ON `users`.`id` = `shift_entries`.`user_id`
LEFT JOIN `shifts` ON `shift_entries`.`shift_id` = `shifts`.`id` LEFT JOIN `shifts` ON `shift_entries`.`shift_id` = `shifts`.`id`
WHERE `users`.`id` = ? WHERE `users`.`id` = ?
@ -32,8 +32,8 @@ function User_tshirt_score($userId)
', $shift_sum_formula), [ ', $shift_sum_formula), [
$userId, $userId,
]); ]);
if (!isset($result_shifts['tshirt_score'])) { if (!isset($result_shifts['goodie_score'])) {
$result_shifts = ['tshirt_score' => 0]; $result_shifts = ['goodie_score' => 0];
} }
$worklogHours = Worklog::query() $worklogHours = Worklog::query()
@ -41,7 +41,7 @@ function User_tshirt_score($userId)
->where('worked_at', '<=', Carbon::Now()) ->where('worked_at', '<=', Carbon::Now())
->sum('hours'); ->sum('hours');
return $result_shifts['tshirt_score'] + $worklogHours; return $result_shifts['goodie_score'] + $worklogHours;
} }
/** /**

View File

@ -58,7 +58,7 @@ function admin_active()
if ($request->hasPostData('ack')) { if ($request->hasPostData('ack')) {
State::query() State::query()
->where('got_shirt', '=', false) ->where('got_goodie', '=', false)
->update(['active' => false]); ->update(['active' => false]);
$query = User::query() $query = User::query()
@ -140,7 +140,7 @@ function admin_active()
$user_id = $request->input('tshirt'); $user_id = $request->input('tshirt');
$user_source = User::find($user_id); $user_source = User::find($user_id);
if ($user_source) { if ($user_source) {
$user_source->state->got_shirt = true; $user_source->state->got_goodie = true;
$user_source->state->save(); $user_source->state->save();
engelsystem_log('User ' . User_Nick_render($user_source, true) . ' has tshirt now.'); engelsystem_log('User ' . User_Nick_render($user_source, true) . ' has tshirt now.');
$msg = success(($goodie_tshirt ? __('Angel has got a T-shirt.') : __('Angel has got a goodie.')), true); $msg = success(($goodie_tshirt ? __('Angel has got a T-shirt.') : __('Angel has got a goodie.')), true);
@ -151,7 +151,7 @@ function admin_active()
$user_id = $request->input('not_tshirt'); $user_id = $request->input('not_tshirt');
$user_source = User::find($user_id); $user_source = User::find($user_id);
if ($user_source) { if ($user_source) {
$user_source->state->got_shirt = false; $user_source->state->got_goodie = false;
$user_source->state->save(); $user_source->state->save();
engelsystem_log('User ' . User_Nick_render($user_source, true) . ' has NO tshirt.'); engelsystem_log('User ' . User_Nick_render($user_source, true) . ' has NO tshirt.');
$msg = success(($goodie_tshirt ? __('Angel has got no T-shirt.') : __('Angel has got no goodie.')), true); $msg = success(($goodie_tshirt ? __('Angel has got no T-shirt.') : __('Angel has got no goodie.')), true);
@ -257,7 +257,7 @@ function admin_active()
. ' min (' . sprintf('%.2f', $usr['shift_length'] / 3600) . '&nbsp;h)'; . ' min (' . sprintf('%.2f', $usr['shift_length'] / 3600) . '&nbsp;h)';
$userData['active'] = icon_bool($usr->state->active); $userData['active'] = icon_bool($usr->state->active);
$userData['force_active'] = icon_bool($usr->state->force_active); $userData['force_active'] = icon_bool($usr->state->force_active);
$userData['tshirt'] = icon_bool($usr->state->got_shirt); $userData['tshirt'] = icon_bool($usr->state->got_goodie);
$userData['shift_count'] = $usr['shift_count']; $userData['shift_count'] = $usr['shift_count'];
$actions = []; $actions = [];
@ -291,7 +291,7 @@ function admin_active()
true true
); );
} }
if (!$usr->state->got_shirt) { if (!$usr->state->got_goodie) {
$parametersShirt = [ $parametersShirt = [
'tshirt' => $usr->id, 'tshirt' => $usr->id,
'search' => $search, 'search' => $search,
@ -309,7 +309,7 @@ function admin_active()
); );
} }
} }
if ($usr->state->got_shirt) { if ($usr->state->got_goodie) {
$parameters = [ $parameters = [
'not_tshirt' => $usr->id, 'not_tshirt' => $usr->id,
'search' => $search, 'search' => $search,
@ -343,7 +343,7 @@ function admin_active()
$gc = State::query() $gc = State::query()
->leftJoin('users_settings', 'users_state.user_id', '=', 'users_settings.user_id') ->leftJoin('users_settings', 'users_state.user_id', '=', 'users_settings.user_id')
->leftJoin('users_personal_data', 'users_state.user_id', '=', 'users_personal_data.user_id') ->leftJoin('users_personal_data', 'users_state.user_id', '=', 'users_personal_data.user_id')
->where('users_state.got_shirt', '=', true) ->where('users_state.got_goodie', '=', true)
->where('users_personal_data.shirt_size', '=', $size) ->where('users_personal_data.shirt_size', '=', $size)
->count(); ->count();
$goodie_statistics[] = [ $goodie_statistics[] = [
@ -355,7 +355,7 @@ function admin_active()
$goodie_statistics[] = array_merge( $goodie_statistics[] = array_merge(
($goodie_tshirt ? ['size' => '<b>' . __('Sum') . '</b>'] : []), ($goodie_tshirt ? ['size' => '<b>' . __('Sum') . '</b>'] : []),
['given' => '<b>' . State::whereGotShirt(true)->count() . '</b>'] ['given' => '<b>' . State::whereGotGoodie(true)->count() . '</b>']
); );
return page_with_title(admin_active_title(), [ return page_with_title(admin_active_title(), [

View File

@ -28,7 +28,7 @@ function admin_user()
$goodie_enabled = $goodie !== GoodieType::None; $goodie_enabled = $goodie !== GoodieType::None;
$goodie_tshirt = $goodie === GoodieType::Tshirt; $goodie_tshirt = $goodie === GoodieType::Tshirt;
$user_info_edit = auth()->can('user.info.edit'); $user_info_edit = auth()->can('user.info.edit');
$user_edit_shirt = auth()->can('user.edit.shirt'); $user_goodie_edit = auth()->can('user.goodie.edit');
$user_edit = auth()->can('user.edit'); $user_edit = auth()->can('user.edit');
$admin_arrive = auth()->can('admin_arrive'); $admin_arrive = auth()->can('admin_arrive');
@ -45,7 +45,7 @@ function admin_user()
} }
$html .= __('Here you can change the user entry. Under the item \'Arrived\' the angel is marked as present, a yes at Active means that the angel was active.'); $html .= __('Here you can change the user entry. Under the item \'Arrived\' the angel is marked as present, a yes at Active means that the angel was active.');
if ($goodie_enabled && $user_edit_shirt) { if ($goodie_enabled && $user_goodie_edit) {
if ($goodie_tshirt) { if ($goodie_tshirt) {
$html .= ' ' . __('If the angel is active, it can claim a T-shirt. If T-shirt is set to \'Yes\', the angel already got their T-shirt.'); $html .= ' ' . __('If the angel is active, it can claim a T-shirt. If T-shirt is set to \'Yes\', the angel already got their T-shirt.');
} else { } else {
@ -89,7 +89,7 @@ function admin_user()
. '<input type="email" size="40" name="eemail" value="' . htmlspecialchars($user_source->email) . '" class="form-control" maxlength="254">' . '<input type="email" size="40" name="eemail" value="' . htmlspecialchars($user_source->email) . '" class="form-control" maxlength="254">'
. '</td></tr>' . "\n"; . '</td></tr>' . "\n";
} }
if ($goodie_tshirt && $user_edit_shirt) { if ($goodie_tshirt && $user_goodie_edit) {
$html .= ' <tr><td>' . __('user.shirt_size') . '</td><td>' $html .= ' <tr><td>' . __('user.shirt_size') . '</td><td>'
. html_select_key( . html_select_key(
'size', 'size',
@ -129,7 +129,7 @@ function admin_user()
// Active? // Active?
$html .= ' <tr><td>' . __('user.active') . '</td><td>' . "\n"; $html .= ' <tr><td>' . __('user.active') . '</td><td>' . "\n";
$html .= $user_edit_shirt $html .= $user_goodie_edit
? html_options('eAktiv', $options, $user_source->state->active) ? html_options('eAktiv', $options, $user_source->state->active)
: icon_bool($user_source->state->active); : icon_bool($user_source->state->active);
$html .= '</td></tr>' . "\n"; $html .= '</td></tr>' . "\n";
@ -144,13 +144,13 @@ function admin_user()
} }
if ($goodie_enabled) { if ($goodie_enabled) {
// T-Shirt bekommen? // got goodie?
$html .= ' <tr><td>' $html .= ' <tr><td>'
. ($goodie_tshirt ? __('T-shirt') : __('Goodie')) . ($goodie_tshirt ? __('T-shirt') : __('Goodie'))
. '</td><td>' . "\n"; . '</td><td>' . "\n";
$html .= $user_edit_shirt $html .= $user_goodie_edit
? html_options('eTshirt', $options, $user_source->state->got_shirt) ? html_options('eTshirt', $options, $user_source->state->got_goodie)
: icon_bool($user_source->state->got_shirt); : icon_bool($user_source->state->got_goodie);
$html .= '</td></tr>' . "\n"; $html .= '</td></tr>' . "\n";
} }
@ -317,7 +317,7 @@ function admin_user()
$user_source->personalData->first_name = $request->postData('eVorname'); $user_source->personalData->first_name = $request->postData('eVorname');
$user_source->personalData->last_name = $request->postData('eName'); $user_source->personalData->last_name = $request->postData('eName');
} }
if ($goodie_tshirt && $user_edit_shirt) { if ($goodie_tshirt && $user_goodie_edit) {
$user_source->personalData->shirt_size = $request->postData('eSize'); $user_source->personalData->shirt_size = $request->postData('eSize');
} }
$user_source->personalData->save(); $user_source->personalData->save();
@ -328,8 +328,8 @@ function admin_user()
} }
$user_source->contact->save(); $user_source->contact->save();
if ($goodie_enabled && $user_edit_shirt) { if ($goodie_enabled && $user_goodie_edit) {
$user_source->state->got_shirt = $request->postData('eTshirt'); $user_source->state->got_goodie = $request->postData('eTshirt');
} }
if ($user_info_edit) { if ($user_info_edit) {
$user_source->state->user_info = $request->postData('userInfo'); $user_source->state->user_info = $request->postData('userInfo');
@ -338,7 +338,7 @@ function admin_user()
$user_source->state->arrived = $request->postData('arrive'); $user_source->state->arrived = $request->postData('arrive');
} }
if ($user_edit_shirt) { if ($user_goodie_edit) {
$user_source->state->active = $request->postData('eAktiv'); $user_source->state->active = $request->postData('eAktiv');
} }
if (auth()->can('user.fa.edit') && config('enable_force_active')) { if (auth()->can('user.fa.edit') && config('enable_force_active')) {
@ -356,7 +356,7 @@ function admin_user()
. ', arrived: ' . $user_source->state->arrived . ', arrived: ' . $user_source->state->arrived
. ', active: ' . $user_source->state->active . ', active: ' . $user_source->state->active
. ', force-active: ' . $user_source->state->force_active . ', force-active: ' . $user_source->state->force_active
. ($goodie_tshirt ? ', t-shirt: ' : ', goodie: ' . $user_source->state->got_shirt) . ($goodie_tshirt ? ', t-shirt: ' : ', goodie: ' . $user_source->state->got_goodie)
. ($user_info_edit ? ', user-info: ' . $user_source->state->user_info : '') . ($user_info_edit ? ', user-info: ' . $user_source->state->user_info : '')
); );
$html .= success(__('Changes were saved.') . "\n", true); $html .= success(__('Changes were saved.') . "\n", true);

View File

@ -28,7 +28,7 @@ function header_render_hints()
$hints_renderer->addHint(render_user_pronoun_hint(), true); $hints_renderer->addHint(render_user_pronoun_hint(), true);
$hints_renderer->addHint(render_user_firstname_hint(), true); $hints_renderer->addHint(render_user_firstname_hint(), true);
$hints_renderer->addHint(render_user_lastname_hint(), true); $hints_renderer->addHint(render_user_lastname_hint(), true);
$hints_renderer->addHint(render_user_tshirt_hint(), true); $hints_renderer->addHint(render_user_goodie_hint(), true);
$hints_renderer->addHint(render_user_dect_hint(), true); $hints_renderer->addHint(render_user_dect_hint(), true);
$hints_renderer->addHint(render_user_mobile_hint(), true); $hints_renderer->addHint(render_user_mobile_hint(), true);

View File

@ -71,7 +71,7 @@ function User_edit_vouchers_view($user)
* @param int $active_count * @param int $active_count
* @param int $force_active_count * @param int $force_active_count
* @param int $freeloads_count * @param int $freeloads_count
* @param int $tshirts_count * @param int $goodies_count
* @param int $voucher_count * @param int $voucher_count
* @return string * @return string
*/ */
@ -82,7 +82,7 @@ function Users_view(
$active_count, $active_count,
$force_active_count, $force_active_count,
$freeloads_count, $freeloads_count,
$tshirts_count, $goodies_count,
$voucher_count $voucher_count
) { ) {
$goodie = GoodieType::from(config('goodie_type')); $goodie = GoodieType::from(config('goodie_type'));
@ -105,7 +105,7 @@ function Users_view(
$u['active'] = icon_bool($user->state->active); $u['active'] = icon_bool($user->state->active);
$u['force_active'] = icon_bool($user->state->force_active); $u['force_active'] = icon_bool($user->state->force_active);
if ($goodie_enabled) { if ($goodie_enabled) {
$u['got_shirt'] = icon_bool($user->state->got_shirt); $u['got_goodie'] = icon_bool($user->state->got_goodie);
if ($goodie_tshirt) { if ($goodie_tshirt) {
$u['shirt_size'] = $user->personalData->shirt_size; $u['shirt_size'] = $user->personalData->shirt_size;
} }
@ -136,7 +136,7 @@ function Users_view(
'active' => $active_count, 'active' => $active_count,
'force_active' => $force_active_count, 'force_active' => $force_active_count,
'freeloads' => $freeloads_count, 'freeloads' => $freeloads_count,
'got_shirt' => $tshirts_count, 'got_goodie' => $goodies_count,
'actions' => '<strong>' . count($usersList) . '</strong>', 'actions' => '<strong>' . count($usersList) . '</strong>',
]; ];
@ -163,10 +163,10 @@ function Users_view(
} }
if ($goodie_enabled) { if ($goodie_enabled) {
if ($goodie_tshirt) { if ($goodie_tshirt) {
$user_table_headers['got_shirt'] = Users_table_header_link('got_shirt', __('T-Shirt'), $order_by); $user_table_headers['got_goodie'] = Users_table_header_link('got_goodie', __('T-Shirt'), $order_by);
$user_table_headers['shirt_size'] = Users_table_header_link('shirt_size', __('Size'), $order_by); $user_table_headers['shirt_size'] = Users_table_header_link('shirt_size', __('Size'), $order_by);
} else { } else {
$user_table_headers['got_shirt'] = Users_table_header_link('got_shirt', __('Goodie'), $order_by); $user_table_headers['got_goodie'] = Users_table_header_link('got_goodie', __('Goodie'), $order_by);
} }
} }
$user_table_headers['arrival_date'] = Users_table_header_link( $user_table_headers['arrival_date'] = Users_table_header_link(
@ -413,8 +413,8 @@ function User_view_myshift(Shift $shift, $user_source, $its_me)
* @param Shift[]|Collection $shifts * @param Shift[]|Collection $shifts
* @param User $user_source * @param User $user_source
* @param bool $its_me * @param bool $its_me
* @param string $tshirt_score * @param string $goodie_score
* @param bool $tshirt_admin * @param bool $goodie_admin
* @param Worklog[]|Collection $user_worklogs * @param Worklog[]|Collection $user_worklogs
* @param bool $admin_user_worklog_privilege * @param bool $admin_user_worklog_privilege
* *
@ -424,8 +424,8 @@ function User_view_myshifts(
$shifts, $shifts,
$user_source, $user_source,
$its_me, $its_me,
$tshirt_score, $goodie_score,
$tshirt_admin, $goodie_admin,
$user_worklogs, $user_worklogs,
$admin_user_worklog_privilege $admin_user_worklog_privilege
) { ) {
@ -475,10 +475,10 @@ function User_view_myshifts(
'comment' => '', 'comment' => '',
'actions' => '', 'actions' => '',
]; ];
if ($goodie_enabled && ($its_me || $tshirt_admin || auth()->can('admin_user'))) { if ($goodie_enabled && ($its_me || $goodie_admin || auth()->can('admin_user'))) {
$myshifts_table[] = [ $myshifts_table[] = [
'date' => '<b>' . ($goodie_tshirt ? __('T-shirt score') : __('Goodie score')) . '&trade;:</b>', 'date' => '<b>' . ($goodie_tshirt ? __('T-shirt score') : __('Goodie score')) . '&trade;:</b>',
'duration' => '<b>' . $tshirt_score . '</b>', 'duration' => '<b>' . $goodie_score . '</b>',
'hints' => '', 'hints' => '',
'location' => '', 'location' => '',
'shift_info' => '', 'shift_info' => '',
@ -548,8 +548,8 @@ function User_view_worklog(Worklog $worklog, $admin_user_worklog_privilege)
* @param Group[] $user_groups * @param Group[] $user_groups
* @param Shift[]|Collection $shifts * @param Shift[]|Collection $shifts
* @param bool $its_me * @param bool $its_me
* @param string $tshirt_score * @param string $goodie_score
* @param bool $tshirt_admin * @param bool $goodie_admin
* @param bool $admin_user_worklog_privilege * @param bool $admin_user_worklog_privilege
* @param Worklog[]|Collection $user_worklogs * @param Worklog[]|Collection $user_worklogs
* @param bool $admin_certificates * @param bool $admin_certificates
@ -564,8 +564,8 @@ function User_view(
$user_groups, $user_groups,
$shifts, $shifts,
$its_me, $its_me,
$tshirt_score, $goodie_score,
$tshirt_admin, $goodie_admin,
$admin_user_worklog_privilege, $admin_user_worklog_privilege,
$user_worklogs, $user_worklogs,
$admin_certificates $admin_certificates
@ -578,13 +578,13 @@ function User_view(
$user_name = htmlspecialchars((string) $user_source->personalData->first_name) . ' ' $user_name = htmlspecialchars((string) $user_source->personalData->first_name) . ' '
. htmlspecialchars((string) $user_source->personalData->last_name); . htmlspecialchars((string) $user_source->personalData->last_name);
$myshifts_table = ''; $myshifts_table = '';
if ($its_me || $admin_user_privilege || $tshirt_admin) { if ($its_me || $admin_user_privilege || $goodie_admin) {
$my_shifts = User_view_myshifts( $my_shifts = User_view_myshifts(
$shifts, $shifts,
$user_source, $user_source,
$its_me, $its_me,
$tshirt_score, $goodie_score,
$tshirt_admin, $goodie_admin,
$user_worklogs, $user_worklogs,
$admin_user_worklog_privilege $admin_user_worklog_privilege
); );
@ -629,9 +629,9 @@ function User_view(
div('row', [ div('row', [
div('col-md-12', [ div('col-md-12', [
table_buttons([ table_buttons([
$auth->can('user.edit.shirt') && $goodie_enabled ? button( $auth->can('user.goodie.edit') && $goodie_enabled ? button(
url('/admin/user/' . $user_source->id . '/goodie'), url('/admin/user/' . $user_source->id . '/goodie'),
icon('person') . ($goodie_tshirt ? __('Shirt') : __('Goodie')) icon('person') . ($goodie_tshirt ? __('T-shirt') : __('Goodie'))
) : '', ) : '',
$admin_user_privilege ? button( $admin_user_privilege ? button(
url('/admin-user', ['id' => $user_source->id]), url('/admin-user', ['id' => $user_source->id]),
@ -825,7 +825,7 @@ function User_view_state_admin($freeloader, $user_source)
} elseif ($user_source->state->active) { } elseif ($user_source->state->active) {
$state[] = '<span class="text-success">' . __('user.active') . '</span>'; $state[] = '<span class="text-success">' . __('user.active') . '</span>';
} }
if ($user_source->state->got_shirt && $goodie_enabled) { if ($user_source->state->got_goodie && $goodie_enabled) {
$state[] = '<span class="text-success">' . ($goodie_tshirt ? __('T-shirt') : __('Goodie')) . '</span>'; $state[] = '<span class="text-success">' . ($goodie_tshirt ? __('T-shirt') : __('Goodie')) . '</span>';
} }
} else { } else {
@ -1044,7 +1044,7 @@ function render_user_arrived_hint(bool $is_sys_menu = false)
/** /**
* @return string|null * @return string|null
*/ */
function render_user_tshirt_hint() function render_user_goodie_hint()
{ {
$goodie = GoodieType::from(config('goodie_type')); $goodie = GoodieType::from(config('goodie_type'));
$goodie_tshirt = $goodie === GoodieType::Tshirt; $goodie_tshirt = $goodie === GoodieType::Tshirt;

View File

@ -612,9 +612,6 @@ msgstr "Edit T-shirt"
msgid "user.edit.goodie" msgid "user.edit.goodie"
msgstr "Edit goodie" msgstr "Edit goodie"
msgid "form.shirt"
msgstr "T-shirt"
msgid "user.shirt_size" msgid "user.shirt_size"
msgstr "T-shirt size" msgstr "T-shirt size"

View File

@ -46,8 +46,8 @@
'checked': userdata.state.active, 'checked': userdata.state.active,
}) }} }) }}
{{ f.switch('got_shirt', is_tshirt ? __('user.got_shirt') : __('user.got_goodie'), { {{ f.switch('got_goodie', is_tshirt ? __('user.got_shirt') : __('user.got_goodie'), {
'checked': userdata.state.got_shirt, 'checked': userdata.state.got_goodie,
}) }} }) }}
</div> </div>
<div class="col-md-12"> <div class="col-md-12">

View File

@ -155,7 +155,7 @@
'required': isTShirtSizeRequired, 'required': isTShirtSizeRequired,
'required_icon': isTShirtSizeRequired, 'required_icon': isTShirtSizeRequired,
'default_option': __('form.select_placeholder'), 'default_option': __('form.select_placeholder'),
'disabled': userdata.state.got_shirt, 'disabled': userdata.state.got_goodie,
'info': __('settings.profile.shirt_size.hint'), 'info': __('settings.profile.shirt_size.hint'),
'raw_form_text': true, 'raw_form_text': true,
'form_text': (tShirtLink ? m.icon('info-circle') 'form_text': (tShirtLink ? m.icon('info-circle')

View File

@ -15,14 +15,14 @@ use Engelsystem\Http\Response;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
class UserShirtController extends BaseController class UserGoodieController extends BaseController
{ {
use HasUserNotifications; use HasUserNotifications;
/** @var array<string, string> */ /** @var array<string, string> */
protected array $permissions = [ protected array $permissions = [
'editShirt' => 'user.edit.shirt', 'editGoodie' => 'user.goodie.edit',
'saveShirt' => 'user.edit.shirt', 'saveGoodie' => 'user.goodie.edit',
]; ];
public function __construct( public function __construct(
@ -35,14 +35,14 @@ class UserShirtController extends BaseController
) { ) {
} }
public function editShirt(Request $request): Response public function editGoodie(Request $request): Response
{ {
$userId = (int) $request->getAttribute('user_id'); $userId = (int) $request->getAttribute('user_id');
$user = $this->user->findOrFail($userId); $user = $this->user->findOrFail($userId);
return $this->response->withView( return $this->response->withView(
'admin/user/edit-shirt.twig', 'admin/user/edit-goodie.twig',
[ [
'userdata' => $user, 'userdata' => $user,
'is_tshirt' => $this->config->get('goodie_type') === GoodieType::Tshirt->value, 'is_tshirt' => $this->config->get('goodie_type') === GoodieType::Tshirt->value,
@ -50,7 +50,7 @@ class UserShirtController extends BaseController
); );
} }
public function saveShirt(Request $request): Response public function saveGoodie(Request $request): Response
{ {
$userId = (int) $request->getAttribute('user_id'); $userId = (int) $request->getAttribute('user_id');
$shirtEnabled = $this->config->get('goodie_type') === GoodieType::Tshirt->value; $shirtEnabled = $this->config->get('goodie_type') === GoodieType::Tshirt->value;
@ -61,7 +61,7 @@ class UserShirtController extends BaseController
'shirt_size' => ($shirtEnabled ? 'required' : 'optional') . '|shirt_size', 'shirt_size' => ($shirtEnabled ? 'required' : 'optional') . '|shirt_size',
'arrived' => 'optional|checked', 'arrived' => 'optional|checked',
'active' => 'optional|checked', 'active' => 'optional|checked',
'got_shirt' => 'optional|checked', 'got_goodie' => 'optional|checked',
]); ]);
if ($shirtEnabled) { if ($shirtEnabled) {
@ -74,19 +74,19 @@ class UserShirtController extends BaseController
} }
$user->state->active = (bool) $data['active']; $user->state->active = (bool) $data['active'];
$user->state->got_shirt = (bool) $data['got_shirt']; $user->state->got_goodie = (bool) $data['got_goodie'];
$user->state->save(); $user->state->save();
$this->log->info( $this->log->info(
'Updated user shirt state "{user}" ({id}): ' 'Updated user goodie state "{user}" ({id}): '
. '{size}, arrived: {arrived}, active: {active}, got shirt: {got_shirt}', . '{size}, arrived: {arrived}, active: {active}, got goodie: {got_goodie}',
[ [
'id' => $user->id, 'id' => $user->id,
'user' => $user->name, 'user' => $user->name,
'size' => $user->personalData->shirt_size, 'size' => $user->personalData->shirt_size,
'arrived' => $user->state->arrived ? 'yes' : 'no', 'arrived' => $user->state->arrived ? 'yes' : 'no',
'active' => $user->state->active ? 'yes' : 'no', 'active' => $user->state->active ? 'yes' : 'no',
'got_shirt' => $user->state->got_shirt ? 'yes' : 'no', 'got_goodie' => $user->state->got_goodie ? 'yes' : 'no',
] ]
); );

View File

@ -142,7 +142,7 @@ class Controller extends BaseController
'type' => 'histogram', 'type' => 'histogram',
$this->stats->vouchersBuckets($metrics['voucher']) + ['sum' => $this->stats->vouchers()], $this->stats->vouchersBuckets($metrics['voucher']) + ['sum' => $this->stats->vouchers()],
], ],
'tshirts_issued' => ['type' => 'counter', 'help' => 'Issued T-Shirts', $this->stats->tshirts()], 'goodies_issued' => ['type' => 'counter', 'help' => 'Issued Goodies', $this->stats->goodies()],
'tshirt_sizes' => [ 'tshirt_sizes' => [
'type' => 'gauge', 'type' => 'gauge',
'help' => 'The sizes users have configured', 'help' => 'The sizes users have configured',

View File

@ -146,9 +146,9 @@ class Stats
return $return; return $return;
} }
public function tshirts(): int public function goodies(): int
{ {
return State::whereGotShirt(true)->count(); return State::whereGotGoodie(true)->count();
} }
public function tshirtSizes(): Collection public function tshirtSizes(): Collection

View File

@ -113,7 +113,7 @@ class SettingsController extends BaseController
if ( if (
$goodie_tshirt $goodie_tshirt
&& isset(config('tshirt_sizes')[$data['shirt_size'] ?? '']) && isset(config('tshirt_sizes')[$data['shirt_size'] ?? ''])
&& !$user->state->got_shirt && !$user->state->got_goodie
) { ) {
$user->personalData->shirt_size = $data['shirt_size']; $user->personalData->shirt_size = $data['shirt_size'];
} }
@ -477,7 +477,7 @@ class SettingsController extends BaseController
$rules['planned_arrival_date'] = 'required|date:Y-m-d'; $rules['planned_arrival_date'] = 'required|date:Y-m-d';
$rules['planned_departure_date'] = 'optional|date:Y-m-d'; $rules['planned_departure_date'] = 'optional|date:Y-m-d';
} }
if ($goodie_tshirt && !$user->state->got_shirt) { if ($goodie_tshirt && !$user->state->got_goodie) {
$rules['shirt_size'] = $this->isRequired('tshirt_size') . '|shirt_size'; $rules['shirt_size'] = $this->isRequired('tshirt_size') . '|shirt_size';
} }
return $rules; return $rules;

View File

@ -14,7 +14,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property string|null $user_info * @property string|null $user_info
* @property bool $active * @property bool $active
* @property bool $force_active * @property bool $force_active
* @property bool $got_shirt * @property bool $got_goodie
* @property int $got_voucher * @property int $got_voucher
* *
* @method static QueryBuilder|State[] whereArrived($value) * @method static QueryBuilder|State[] whereArrived($value)
@ -22,7 +22,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @method static QueryBuilder|State[] whereUserInfo($value) * @method static QueryBuilder|State[] whereUserInfo($value)
* @method static QueryBuilder|State[] whereActive($value) * @method static QueryBuilder|State[] whereActive($value)
* @method static QueryBuilder|State[] whereForceActive($value) * @method static QueryBuilder|State[] whereForceActive($value)
* @method static QueryBuilder|State[] whereGotShirt($value) * @method static QueryBuilder|State[] whereGotGoodie($value)
* @method static QueryBuilder|State[] whereGotVoucher($value) * @method static QueryBuilder|State[] whereGotVoucher($value)
*/ */
class State extends HasUserModel class State extends HasUserModel
@ -39,7 +39,7 @@ class State extends HasUserModel
'user_info' => null, 'user_info' => null,
'active' => false, 'active' => false,
'force_active' => false, 'force_active' => false,
'got_shirt' => false, 'got_goodie' => false,
'got_voucher' => 0, 'got_voucher' => 0,
]; ];
@ -49,7 +49,7 @@ class State extends HasUserModel
'arrived' => 'boolean', 'arrived' => 'boolean',
'active' => 'boolean', 'active' => 'boolean',
'force_active' => 'boolean', 'force_active' => 'boolean',
'got_shirt' => 'boolean', 'got_goodie' => 'boolean',
'got_voucher' => 'integer', 'got_voucher' => 'integer',
'arrival_date' => 'datetime', 'arrival_date' => 'datetime',
]; ];
@ -66,7 +66,7 @@ class State extends HasUserModel
'user_info', 'user_info',
'active', 'active',
'force_active', 'force_active',
'got_shirt', 'got_goodie',
'got_voucher', 'got_voucher',
]; ];
} }

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Controllers\Admin; namespace Engelsystem\Test\Unit\Controllers\Admin;
use Engelsystem\Config\GoodieType; use Engelsystem\Config\GoodieType;
use Engelsystem\Controllers\Admin\UserShirtController; use Engelsystem\Controllers\Admin\UserGoodieController;
use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Exceptions\ValidationException; use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Redirector; use Engelsystem\Http\Redirector;
@ -18,13 +18,13 @@ use Engelsystem\Test\Unit\HasDatabase;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
class UserShirtControllerTest extends ControllerTest class UserGoodieControllerTest extends ControllerTest
{ {
use HasDatabase; use HasDatabase;
/** /**
* @covers \Engelsystem\Controllers\Admin\UserShirtController::editShirt * @covers \Engelsystem\Controllers\Admin\UserGoodieController::editGoodie
* @covers \Engelsystem\Controllers\Admin\UserShirtController::__construct * @covers \Engelsystem\Controllers\Admin\UserGoodieController::__construct
*/ */
public function testIndex(): void public function testIndex(): void
{ {
@ -36,15 +36,15 @@ class UserShirtControllerTest extends ControllerTest
$user = new User(); $user = new User();
User::factory()->create(); User::factory()->create();
$this->setExpects($this->response, 'withView', ['admin/user/edit-shirt.twig'], $this->response); $this->setExpects($this->response, 'withView', ['admin/user/edit-goodie.twig'], $this->response);
$controller = new UserShirtController($auth, $this->config, $this->log, $redirector, $this->response, $user); $controller = new UserGoodieController($auth, $this->config, $this->log, $redirector, $this->response, $user);
$controller->editShirt($request); $controller->editGoodie($request);
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\UserShirtController::editShirt * @covers \Engelsystem\Controllers\Admin\UserGoodieController::editGoodie
*/ */
public function testIndexUserNotFound(): void public function testIndexUserNotFound(): void
{ {
@ -54,17 +54,17 @@ class UserShirtControllerTest extends ControllerTest
$redirector = $this->createMock(Redirector::class); $redirector = $this->createMock(Redirector::class);
$user = new User(); $user = new User();
$controller = new UserShirtController($auth, $this->config, $this->log, $redirector, $this->response, $user); $controller = new UserGoodieController($auth, $this->config, $this->log, $redirector, $this->response, $user);
$this->expectException(ModelNotFoundException::class); $this->expectException(ModelNotFoundException::class);
$controller->editShirt($this->request); $controller->editGoodie($this->request);
} }
/** /**
* @todo Factor out separate tests. Isolated User, Config and permissions per test. * @todo Factor out separate tests. Isolated User, Config and permissions per test.
* @covers \Engelsystem\Controllers\Admin\UserShirtController::saveShirt * @covers \Engelsystem\Controllers\Admin\UserGoodieController::saveGoodie
*/ */
public function testSaveShirt(): void public function testSaveGoodie(): void
{ {
$this->config->set('goodie_type', GoodieType::Tshirt->value); $this->config->set('goodie_type', GoodieType::Tshirt->value);
$request = $this->request $request = $this->request
@ -89,7 +89,7 @@ class UserShirtControllerTest extends ControllerTest
->willReturnOnConsecutiveCalls(true, true, false, false, true); ->willReturnOnConsecutiveCalls(true, true, false, false, true);
$this->setExpects($redirector, 'back', null, $this->response, $this->exactly(5)); $this->setExpects($redirector, 'back', null, $this->response, $this->exactly(5));
$controller = new UserShirtController( $controller = new UserGoodieController(
$auth, $auth,
$this->config, $this->config,
$this->log, $this->log,
@ -100,32 +100,32 @@ class UserShirtControllerTest extends ControllerTest
$controller->setValidator(new Validator()); $controller->setValidator(new Validator());
// Set shirt size // Set shirt size
$controller->saveShirt($request); $controller->saveGoodie($request);
$this->assertHasNotification('user.edit.success'); $this->assertHasNotification('user.edit.success');
$this->assertTrue($this->log->hasInfoThatContains('Updated user shirt state')); $this->assertTrue($this->log->hasInfoThatContains('Updated user goodie state'));
$user = User::find(1); $user = User::find(1);
$this->assertEquals('S', $user->personalData->shirt_size); $this->assertEquals('S', $user->personalData->shirt_size);
$this->assertFalse($user->state->arrived); $this->assertFalse($user->state->arrived);
$this->assertFalse($user->state->active); $this->assertFalse($user->state->active);
$this->assertFalse($user->state->got_shirt); $this->assertFalse($user->state->got_goodie);
// Set active, arrived and got_shirt // Set active, arrived and got_goodie
$request = $request $request = $request
->withParsedBody([ ->withParsedBody([
'shirt_size' => 'S', 'shirt_size' => 'S',
'arrived' => '1', 'arrived' => '1',
'active' => '1', 'active' => '1',
'got_shirt' => '1', 'got_goodie' => '1',
]); ]);
$controller->saveShirt($request); $controller->saveGoodie($request);
$user = User::find(1); $user = User::find(1);
$this->assertTrue($user->state->active); $this->assertTrue($user->state->active);
$this->assertTrue($user->state->arrived); $this->assertTrue($user->state->arrived);
$this->assertTrue($user->state->got_shirt); $this->assertTrue($user->state->got_goodie);
// Shirt size not available // Shirt size not available
$request = $request $request = $request
@ -134,7 +134,7 @@ class UserShirtControllerTest extends ControllerTest
]); ]);
try { try {
$controller->saveShirt($request); $controller->saveGoodie($request);
self::fail('Expected exception was not raised'); self::fail('Expected exception was not raised');
} catch (ValidationException) { } catch (ValidationException) {
// ignore // ignore
@ -152,18 +152,18 @@ class UserShirtControllerTest extends ControllerTest
$user->state->arrived = false; $user->state->arrived = false;
$user->state->save(); $user->state->save();
$this->assertFalse($user->state->arrived); $this->assertFalse($user->state->arrived);
$controller->saveShirt($request); $controller->saveGoodie($request);
$user = User::find(1); $user = User::find(1);
$this->assertFalse($user->state->arrived); $this->assertFalse($user->state->arrived);
// Shirt disabled // Goodie disabled
$this->config->set('goodie_type', GoodieType::None->value); $this->config->set('goodie_type', GoodieType::None->value);
$request = $request $request = $request
->withParsedBody([ ->withParsedBody([
'shirt_size' => 'XS', 'shirt_size' => 'XS',
]); ]);
$controller->saveShirt($request); $controller->saveGoodie($request);
$user = User::find(1); $user = User::find(1);
$this->assertEquals('S', $user->personalData->shirt_size); $this->assertEquals('S', $user->personalData->shirt_size);
@ -174,15 +174,15 @@ class UserShirtControllerTest extends ControllerTest
'shirt_size' => 'XS', 'shirt_size' => 'XS',
]); ]);
$controller->saveShirt($request); $controller->saveGoodie($request);
$user = User::find(1); $user = User::find(1);
$this->assertEquals('XS', $user->personalData->shirt_size); $this->assertEquals('XS', $user->personalData->shirt_size);
} }
/** /**
* @covers \Engelsystem\Controllers\Admin\UserShirtController::saveShirt * @covers \Engelsystem\Controllers\Admin\UserGoodieController::saveGoodie
*/ */
public function testSaveShirtUserNotFound(): void public function testSaveGoodieUserNotFound(): void
{ {
/** @var Authenticator|MockObject $auth */ /** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class); $auth = $this->createMock(Authenticator::class);
@ -190,9 +190,9 @@ class UserShirtControllerTest extends ControllerTest
$redirector = $this->createMock(Redirector::class); $redirector = $this->createMock(Redirector::class);
$user = new User(); $user = new User();
$controller = new UserShirtController($auth, $this->config, $this->log, $redirector, $this->response, $user); $controller = new UserGoodieController($auth, $this->config, $this->log, $redirector, $this->response, $user);
$this->expectException(ModelNotFoundException::class); $this->expectException(ModelNotFoundException::class);
$controller->editShirt($this->request); $controller->editGoodie($this->request);
} }
} }

View File

@ -52,7 +52,7 @@ class ControllerTest extends TestCase
$this->assertArrayHasKey('work_seconds', $data); $this->assertArrayHasKey('work_seconds', $data);
$this->assertArrayHasKey('worklog_seconds', $data); $this->assertArrayHasKey('worklog_seconds', $data);
$this->assertArrayHasKey('vouchers', $data); $this->assertArrayHasKey('vouchers', $data);
$this->assertArrayHasKey('tshirts_issued', $data); $this->assertArrayHasKey('goodies_issued', $data);
$this->assertArrayHasKey('tshirt_sizes', $data); $this->assertArrayHasKey('tshirt_sizes', $data);
$this->assertArrayHasKey('locales', $data); $this->assertArrayHasKey('locales', $data);
$this->assertArrayHasKey('themes', $data); $this->assertArrayHasKey('themes', $data);
@ -141,7 +141,7 @@ class ControllerTest extends TestCase
->willReturnOnConsecutiveCalls(0, 1, 0, 5, 999, 4, 55, 3); ->willReturnOnConsecutiveCalls(0, 1, 0, 5, 999, 4, 55, 3);
$this->setExpects($stats, 'worklogSeconds', null, 39 * 60 * 60); $this->setExpects($stats, 'worklogSeconds', null, 39 * 60 * 60);
$this->setExpects($stats, 'vouchers', null, 17); $this->setExpects($stats, 'vouchers', null, 17);
$this->setExpects($stats, 'tshirts', null, 3); $this->setExpects($stats, 'goodies', null, 3);
$this->setExpects($stats, 'tshirtSizes', null, new Collection([ $this->setExpects($stats, 'tshirtSizes', null, new Collection([
['shirt_size' => 'L', 'count' => 2], ['shirt_size' => 'L', 'count' => 2],
])); ]));

View File

@ -59,14 +59,14 @@ class StatsTest extends TestCase
} }
/** /**
* @covers \Engelsystem\Controllers\Metrics\Stats::tshirts * @covers \Engelsystem\Controllers\Metrics\Stats::goodies
*/ */
public function testTshirts(): void public function testGoodies(): void
{ {
$this->addUsers(); $this->addUsers();
$stats = new Stats($this->database); $stats = new Stats($this->database);
$this->assertEquals(2, $stats->tshirts()); $this->assertEquals(2, $stats->goodies());
} }
/** /**
@ -539,8 +539,8 @@ class StatsTest extends TestCase
'ifsg_confirmed' => true, 'ifsg_confirmed' => true,
] ]
); );
$this->addUser(['arrived' => 1, 'active' => 1, 'got_shirt' => true, 'force_active' => true]); $this->addUser(['arrived' => 1, 'active' => 1, 'got_goodie' => true, 'force_active' => true]);
$this->addUser(['arrived' => 1, 'active' => 1, 'got_shirt' => true], ['shirt_size' => 'L'], ['theme' => 4]); $this->addUser(['arrived' => 1, 'active' => 1, 'got_goodie' => true], ['shirt_size' => 'L'], ['theme' => 4]);
} }
protected function addUser( protected function addUser(