Skip to content

Commit 101b8af

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents 5df5c47 + 57d3aba commit 101b8af

File tree

9 files changed

+322
-35
lines changed

9 files changed

+322
-35
lines changed

app/Http/Controllers/Accessories/AccessoriesController.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,10 @@ public function destroy($accessoryId) : RedirectResponse
220220
*/
221221
public function show(Accessory $accessory) : View | RedirectResponse
222222
{
223-
$accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessory->id);
223+
$accessory->loadCount('checkouts as checkouts_count');
224+
225+
$accessory->load(['adminuser' => fn($query) => $query->withTrashed()]);
226+
224227
$this->authorize('view', $accessory);
225228
return view('accessories.view', compact('accessory'));
226229
}

app/Livewire/SlackSettingsForm.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function mount() {
7171

7272
$this->setting = Setting::getSettings();
7373
$this->save_button = trans('general.save');
74-
$this->webhook_selected = $this->setting->webhook_selected ?? 'slack';
74+
$this->webhook_selected = ($this->setting->webhook_selected !== '') ? $this->setting->webhook_selected : 'slack';
7575
$this->webhook_name = $this->webhook_text[$this->setting->webhook_selected]["name"] ?? $this->webhook_text['slack']["name"];
7676
$this->webhook_icon = $this->webhook_text[$this->setting->webhook_selected]["icon"] ?? $this->webhook_text['slack']["icon"];
7777
$this->webhook_placeholder = $this->webhook_text[$this->setting->webhook_selected]["placeholder"] ?? $this->webhook_text['slack']["placeholder"];
@@ -191,7 +191,6 @@ public function clearSettings(){
191191
$this->setting->webhook_endpoint = '';
192192
$this->setting->webhook_channel = '';
193193
$this->setting->webhook_botname = '';
194-
$this->setting->webhook_selected = '';
195194

196195
$this->setting->save();
197196

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Support\Facades\DB;
5+
6+
return new class extends Migration {
7+
/**
8+
* Run the migrations.
9+
*/
10+
public function up(): void
11+
{
12+
$settings = DB::table('settings')->first();
13+
14+
if ($settings) {
15+
/** If webhook settings were cleared via the integration settings page,
16+
* the webhook_selected was cleared as well when it should have reset to "slack".
17+
*/
18+
if (
19+
empty($settings->webhook_selected) &&
20+
(empty($settings->webhook_botname) && empty($settings->webhook_channel) && empty($settings->webhook_endpoint))
21+
) {
22+
DB::table('settings')->update(['webhook_selected' => 'slack']);
23+
}
24+
25+
/** If webhook settings were cleared via the integration settings page,
26+
* then slack settings were re-added; then webhook_selected was not being set to "slack" as needed.
27+
*/
28+
if (str_contains($settings->webhook_endpoint, 'slack.com')) {
29+
DB::table('settings')->update(['webhook_selected' => 'slack']);
30+
}
31+
}
32+
}
33+
34+
/**
35+
* Reverse the migrations.
36+
*/
37+
public function down(): void
38+
{
39+
//
40+
}
41+
};

resources/views/accessories/view.blade.php

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -317,20 +317,18 @@ class="table table-striped snipe-table"
317317

318318
@endif
319319

320-
<div class="row">
321-
<div class="col-md-3" style="padding-bottom: 10px;">
322-
<strong>
323-
{{ trans('general.created_by') }}
324-
</strong>
325-
</div>
326-
<div class="col-md-9" style="word-wrap: break-word;">
327-
@if ($accessory->adminuser)
328-
{{ $accessory->adminuser->present()->fullName() }}
329-
@else
330-
{{ trans('admin/reports/general.deleted_user') }}
331-
@endif
320+
@if ($accessory->adminuser)
321+
<div class="row">
322+
<div class="col-md-3" style="padding-bottom: 10px;">
323+
<strong>
324+
{{ trans('general.created_by') }}
325+
</strong>
326+
</div>
327+
<div class="col-md-9" style="word-wrap: break-word;">
328+
<x-full-user-name :user="$accessory->adminuser" />
329+
</div>
332330
</div>
333-
</div>
331+
@endif
334332

335333
</div>
336334

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@props([
2+
'user'
3+
])
4+
5+
@if($user)
6+
@php
7+
$fullName = $user->present()->fullName();
8+
@endphp
9+
10+
@can('view', $user)
11+
@if(! $user->trashed())
12+
{{-- if the user is in database but soft-deleted --}}
13+
<a href="{{ route('users.show', $user->id) }}">{{ $fullName }}</a>
14+
@else
15+
{{-- if the user exists --}}
16+
<s><a href="{{ route('users.show', $user->id) }}">{{ $fullName }}</a></s>
17+
@endif
18+
@else
19+
@if(! $user->trashed())
20+
{{-- if the user is in database but soft-deleted --}}
21+
<span>{{ $fullName }}</span>
22+
@else
23+
{{-- if the user exists --}}
24+
<s><span>{{ $fullName }}</span></s>
25+
@endif
26+
@endcan
27+
@endif

resources/views/livewire/slack-settings-form.blade.php

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
:options="['slack' => trans('admin/settings/general.slack'), 'general' => trans('admin/settings/general.general_webhook'),'google' => trans('admin/settings/general.google_workspaces'), 'microsoft' => trans('admin/settings/general.ms_teams')]"
7373
:selected="old('webhook_selected', $webhook_selected)"
7474
:disabled="Helper::isDemoMode()"
75+
:for-livewire="true"
7576
data-minimum-results-for-search="-1"
7677
class="form-control"
7778
style="width:100%"
@@ -174,22 +175,3 @@ class="btn btn-default btn-sm pull-left">
174175
</div> <!-- /.row -->
175176
</form>
176177
</div> <!-- /livewire div -->
177-
178-
179-
180-
181-
@section('moar_scripts')
182-
<script>
183-
$(document).ready(function () {
184-
$('#select2').select2();
185-
$('#select2').on('change', function (e) {
186-
var data = $('#select2').select2("val");
187-
@this.set('webhook_selected', data);
188-
});
189-
});
190-
191-
192-
</script>
193-
@endsection
194-
195-
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace Tests\Feature\Assets\Api;
4+
5+
use App\Models\Asset;
6+
use App\Models\AssetModel;
7+
use App\Models\Statuslabel;
8+
use App\Models\User;
9+
use PHPUnit\Framework\Attributes\Test;
10+
use Tests\TestCase;
11+
12+
/**
13+
* You could argue that this should go somewhere else - that'd be fair.
14+
* But, as of now, the only way to properly ensure that the counters are set properly
15+
* is to directly hit the app. So that's what this does - via API.
16+
*/
17+
class CheckinCheckoutCounters extends TestCase
18+
{
19+
#[Test]
20+
function counters()
21+
{
22+
//make an admin who can check in and out stuff
23+
$admin = User::factory()->superuser()->create();
24+
25+
//make a user
26+
$user = User::factory()->create();
27+
28+
//need a model for the asset
29+
$model = AssetModel::factory()->create();
30+
31+
//need a status for the asset, too
32+
$status = Statuslabel::factory()->readyToDeploy()->create();
33+
34+
35+
//make an asset using the API (this is for the API after all!)
36+
$response = $this->actingAsForApi($admin)
37+
->postJson(route('api.assets.store'), [
38+
'asset_tag' => 'random_string',
39+
'model_id' => $model->id,
40+
'status_id' => $status->id,
41+
])->assertOk()
42+
->assertStatusMessageIs('success')
43+
->json();
44+
\Log::error(print_r($response, true));
45+
46+
//check the counters
47+
$asset = Asset::find($response['payload']['id']);
48+
$this->assertEquals(0, $asset->checkin_counter);
49+
$this->assertEquals(0, $asset->checkout_counter);
50+
51+
//do a checkout
52+
$this->actingAsForApi($admin)
53+
->postJson(route('api.asset.checkout', $asset), [
54+
'checkout_to_type' => 'user',
55+
'assigned_user' => $user->id,
56+
'checkout_at' => '2024-04-01',
57+
'expected_checkin' => '2024-04-08',
58+
'name' => 'Changed Name',
59+
'note' => 'Here is a cool note!',
60+
])
61+
->assertOk();
62+
63+
$asset->refresh();
64+
//check the counters. both.
65+
$this->assertEquals(0, $asset->checkin_counter);
66+
$this->assertEquals(1, $asset->checkout_counter); //why does _this_ fail?!
67+
68+
//do a checkin
69+
$this->actingAsForApi(User::factory()->checkinAssets()->create())
70+
->postJson(route('api.asset.checkin', $asset), [
71+
'name' => 'Changed Name',
72+
'status_id' => $status->id,
73+
])
74+
->assertOk();
75+
76+
//check the counters, again.
77+
$asset->refresh();
78+
$this->assertEquals(1, $asset->checkin_counter); //wait, _this_ fails too?! WTH?
79+
$this->assertEquals(1, $asset->checkout_counter); //okay, _nothing_ works. Now I'm confused.
80+
}
81+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Tests\Feature\Assets\Ui;
4+
5+
use App\Models\Asset;
6+
use App\Models\AssetModel;
7+
use App\Models\Statuslabel;
8+
use App\Models\User;
9+
use PHPUnit\Framework\Attributes\Test;
10+
use Tests\TestCase;
11+
12+
class CheckinCheckoutCounters extends TestCase
13+
{
14+
#[Test]
15+
function counters()
16+
{
17+
$admin = User::factory()->admin()->create();
18+
$user = User::factory()->create();
19+
20+
// create an asset using the GUI
21+
$this->actingAs($admin)
22+
->post(route('hardware.store'), [
23+
'asset_tags' => ['1' => '1234'],
24+
'model_id' => AssetModel::factory()->create()->id,
25+
'status_id' => Statuslabel::factory()->readyToDeploy()->create()->id,
26+
])->assertRedirect();
27+
28+
$asset = Asset::where('asset_tag', '1234')->sole();
29+
30+
//ensure counters are initialized properly
31+
$this->assertEquals(0,$asset->checkout_counter);
32+
$this->assertEquals(0,$asset->checkin_counter);
33+
34+
//perform a checkout
35+
$this->actingAs($admin)
36+
->post(route('hardware.checkout.store', $asset), [
37+
'checkout_to_type' => 'user',
38+
// overwrite the value from the default fields set above
39+
'assigned_user' => (string) $user->id,
40+
'name' => 'Changed Name',
41+
'checkout_at' => '2024-03-18',
42+
'expected_checkin' => '2024-03-28',
43+
'note' => 'An awesome note',
44+
])->assertRedirect()->assertSessionHasNoErrors();
45+
46+
$asset->refresh();
47+
// dump($asset);
48+
$this->assertEquals(1,$asset->checkout_counter);
49+
$this->assertEquals(0,$asset->checkin_counter);
50+
51+
//perform a check-in
52+
$this->actingAs($admin)
53+
->post(
54+
route('hardware.checkin.store', [$asset]),
55+
[
56+
'name' => 'Changed Name Again',
57+
],
58+
)->assertRedirect()->assertSessionHasNoErrors();
59+
60+
$asset->refresh();
61+
// dump($asset);
62+
$this->assertEquals(1,$asset->checkout_counter);
63+
$this->assertEquals(1,$asset->checkin_counter);
64+
}
65+
}

0 commit comments

Comments
 (0)