3
0
mirror of https://github.com/snipe/snipe-it.git synced 2025-10-29 11:21:21 +00:00

Merge remote-tracking branch 'origin/develop'

Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	resources/views/notifications/markdown/report-expiring-assets.blade.php
This commit is contained in:
snipe 2025-08-29 10:08:56 +01:00
commit 560bd6da92
45 changed files with 513 additions and 82 deletions

View File

@ -59,6 +59,9 @@ class PaveIt extends Command
'migrations',
'settings',
'users',
'telescope_entries',
'telescope_entries_tags',
'telescope_monitoring',
];
// We only need to find out what these are so we can nuke these columns on the assets table.

View File

@ -65,7 +65,7 @@ class Purge extends Command
$maintenances = 0;
foreach ($assets as $asset) {
$this->info('- Asset "'.$asset->present()->name().'" deleted.');
$this->info('- Asset "'.$asset->display_name.'" deleted.');
$asset_assoc += $asset->assetlog()->count();
$asset->assetlog()->forceDelete();
$maintenances += $asset->maintenances()->count();

View File

@ -76,7 +76,7 @@ class ComponentsTransformer
$array[] = [
'assigned_pivot_id' => $asset->pivot->id,
'id' => (int) $asset->id,
'name' => e($asset->model->present()->name).' '.e($asset->present()->name),
'name' => e($asset->model->display_name).' '.e($asset->display_name),
'qty' => $asset->pivot->assigned_qty,
'note' => $asset->pivot->note,
'type' => 'asset',

View File

@ -4,7 +4,6 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\Asset;
use Illuminate\Database\Eloquent\Collection;
class ProfileTransformer

View File

@ -4,6 +4,7 @@ namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\Acceptable;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Carbon\Carbon;

View File

@ -7,19 +7,20 @@ use App\Exceptions\CheckoutNotAllowed;
use App\Helpers\Helper;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Traits\Acceptable;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use App\Presenters\AssetPresenter;
use App\Presenters\Presentable;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Watson\Validating\ValidatingTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
/**
* Model for Assets.

View File

@ -2,14 +2,16 @@
namespace App\Models;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Watson\Validating\ValidatingTrait;
/**
* Model for Companies.
*

View File

@ -3,13 +3,13 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Watson\Validating\ValidatingTrait;
/**

View File

@ -4,22 +4,16 @@ namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\Acceptable;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\ConsumablePresenter;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
use Watson\Validating\ValidatingTrait;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Presenters\ConsumablePresenter;
use App\Models\Actionlog;
use App\Models\ConsumableAssignment;
use App\Models\User;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Supplier;
use App\Models\Category;
class Consumable extends SnipeModel
{

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Traits\CompanyableTrait;
use Illuminate\Database\Eloquent\Model;
use Watson\Validating\ValidatingTrait;

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\Searchable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Watson\Validating\ValidatingTrait;

View File

@ -3,14 +3,14 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Watson\Validating\ValidatingTrait;

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Models\Traits\Acceptable;
use App\Models\Traits\CompanyableChildTrait;
use App\Notifications\CheckinLicenseNotification;
use App\Notifications\CheckoutLicenseNotification;
use App\Presenters\Presentable;

View File

@ -3,16 +3,11 @@
namespace App\Models;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Asset;
use App\Models\Setting;
use App\Models\SnipeModel;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Models\User;
use App\Presenters\Presentable;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;

View File

@ -3,12 +3,13 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\CompanyableChildTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Watson\Validating\ValidatingTrait;
use App\Models\Traits\HasUploads;
/**
* Model for Asset Maintenances.

View File

@ -1,6 +1,8 @@
<?php
namespace App\Models;
namespace App\Models\Traits;
use App\Models\CompanyableChildScope;
trait CompanyableChildTrait
{

View File

@ -1,6 +1,9 @@
<?php
namespace App\Models;
namespace App\Models\Traits;
use App\Models\CompanyableScope;
use App\Models\Setting;
trait CompanyableTrait
{

View File

@ -3,9 +3,11 @@
namespace App\Models;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Traits\Searchable;
use App\Models\Traits\CompanyableTrait;
use App\Models\Traits\HasUploads;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use App\Presenters\UserPresenter;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
@ -13,6 +15,7 @@ use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
@ -22,8 +25,6 @@ use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use Laravel\Passport\HasApiTokens;
use Watson\Validating\ValidatingTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use App\Presenters\UserPresenter;
class User extends SnipeModel implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract, HasLocalePreference
{

View File

@ -93,7 +93,7 @@ use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
}
$message = class_basename(get_class($params['item'])) . ' Audited By '.$admin_user->display_name;
$details = [
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.asset') => htmlspecialchars_decode($item->display_name),
trans('mail.notes') => $note ?: '',
trans('general.location') => $location ?: '',
];

View File

@ -90,7 +90,7 @@ class CheckinAccessoryNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -107,7 +107,7 @@ class CheckinAccessoryNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('Accessory_Checkin_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(htmlspecialchars_decode($item->display_name), '', 'activityTitle')
->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '')
->fact(trans('mail.Accessory_Checkin_Notification')." by ", $admin->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
@ -116,7 +116,7 @@ class CheckinAccessoryNotification extends Notification
$message = trans('mail.Accessory_Checkin_Notification');
$details = [
trans('mail.accessory_name') => htmlspecialchars_decode($item->present()->name),
trans('mail.accessory_name') => htmlspecialchars_decode($item->display_name),
trans('mail.checked_into') => $item->location->name ? $item->location->name : '',
trans('mail.Accessory_Checkin_Notification'). ' by' => $admin->display_name,
trans('admin/consumables/general.remaining')=> $item->numRemaining(),
@ -135,7 +135,7 @@ class CheckinAccessoryNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Accessory_Checkin_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -97,7 +97,7 @@ class CheckinAssetNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -114,7 +114,7 @@ class CheckinAssetNotification extends Notification
->type('success')
->title(trans('mail.Asset_Checkin_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText')
->fact(htmlspecialchars_decode($item->display_name), '', 'activityText')
->fact(trans('mail.checked_into'), ($item->location) ? $item->location->name : '')
->fact(trans('mail.Asset_Checkin_Notification') . " by ", $admin->display_name)
->fact(trans('admin/hardware/form.status'), $item->assetstatus?->name)
@ -124,7 +124,7 @@ class CheckinAssetNotification extends Notification
$message = trans('mail.Asset_Checkin_Notification');
$details = [
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.asset') => htmlspecialchars_decode($item->display_name),
trans('mail.checked_into') => ($item->location) ? $item->location->name : '',
trans('mail.Asset_Checkin_Notification')." by " => $admin->display_name,
trans('admin/hardware/form.status') => $item->assetstatus?->name,
@ -145,7 +145,7 @@ class CheckinAssetNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Asset_Checkin_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -100,7 +100,7 @@ class CheckinComponentNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -118,7 +118,7 @@ class CheckinComponentNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.Component_checkin_notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'header')
->fact(htmlspecialchars_decode($item->display_name), '', 'header')
->fact(trans('mail.Component_checkin_notification')." by ", $admin->display_name ?: 'CLI tool')
->fact(trans('mail.checkedin_from'), $target->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
@ -147,7 +147,7 @@ class CheckinComponentNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Component_checkin_notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -101,7 +101,7 @@ class CheckinLicenseSeatNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -119,7 +119,7 @@ class CheckinLicenseSeatNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.License_Checkin_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'header')
->fact(htmlspecialchars_decode($item->display_name), '', 'header')
->fact(trans('mail.License_Checkin_Notification')." by ", $admin->display_name ?: 'CLI tool')
->fact(trans('mail.checkedin_from'), $target->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count())
@ -129,7 +129,7 @@ class CheckinLicenseSeatNotification extends Notification
$message = trans('mail.License_Checkin_Notification');
$details = [
trans('mail.checkedin_from')=> $target->display_name,
trans('mail.license_for') => htmlspecialchars_decode($item->present()->name),
trans('mail.license_for') => htmlspecialchars_decode($item->display_name),
trans('mail.License_Checkin_Notification')." by " => $admin->display_name ?: 'CLI tool',
trans('admin/consumables/general.remaining') => $item->availCount()->count(),
trans('mail.notes') => $note ?: '',
@ -149,7 +149,7 @@ class CheckinLicenseSeatNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.License_Checkin_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -117,7 +117,7 @@ class CheckoutAccessoryNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($this->checkout_qty.' x '.$item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($this->checkout_qty.' x '.$item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -136,8 +136,8 @@ class CheckoutAccessoryNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.Accessory_Checkout_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(trans('mail.assigned_to'), $target->present()->name)
->fact(htmlspecialchars_decode($item->display_name), '', 'activityTitle')
->fact(trans('mail.assigned_to'), $target->display_name)
->fact(trans('general.qty'), $this->checkout_qty)
->fact(trans('mail.checkedout_from'), $item->location->name ? $item->location->name : '')
->fact(trans('mail.Accessory_Checkout_Notification') . " by ", $admin->display_name)
@ -148,7 +148,7 @@ class CheckoutAccessoryNotification extends Notification
$message = trans('mail.Accessory_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->present()->name,
trans('mail.accessory_name') => htmlspecialchars_decode($item->present()->name),
trans('mail.accessory_name') => htmlspecialchars_decode($item->display_name),
trans('general.qty') => $this->checkout_qty,
trans('mail.checkedout_from') => $item->location->name ? $item->location->name : '',
trans('mail.Accessory_Checkout_Notification'). ' by' => $admin->display_name,
@ -169,7 +169,7 @@ class CheckoutAccessoryNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Accessory_Checkout_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -114,7 +114,7 @@ class CheckoutAssetNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -133,8 +133,8 @@ class CheckoutAssetNotification extends Notification
->type('success')
->title(trans('mail.Asset_Checkout_Notification'))
->addStartGroupToSection('activityText')
->fact(trans('mail.assigned_to'), $target->present()->name)
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText')
->fact(trans('mail.assigned_to'), $target->display_name)
->fact(htmlspecialchars_decode($item->display_name), '', 'activityText')
->fact(trans('mail.Asset_Checkout_Notification') . " by ", $admin->display_name)
->fact(trans('mail.notes'), $note ?: '');
}
@ -142,7 +142,7 @@ class CheckoutAssetNotification extends Notification
$message = trans('mail.Asset_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->present()->name,
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.asset') => htmlspecialchars_decode($item->display_name),
trans('mail.Asset_Checkout_Notification'). ' by' => $admin->display_name,
trans('mail.notes') => $note ?: '',
];
@ -160,7 +160,7 @@ public function toGoogleChat()
Card::create()
->header(
'<strong>'.trans('mail.Asset_Checkout_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -97,7 +97,7 @@ class CheckoutComponentNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -116,7 +116,7 @@ class CheckoutComponentNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.Component_checkout_notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(htmlspecialchars_decode($item->display_name), '', 'activityTitle')
->fact(trans('mail.Component_checkout_notification')." by ", $admin->display_name)
->fact(trans('mail.assigned_to'), $target->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
@ -126,7 +126,7 @@ class CheckoutComponentNotification extends Notification
$message = trans('mail.Component_checkout_notification');
$details = [
trans('mail.assigned_to') => $target->display_name,
trans('mail.item') => htmlspecialchars_decode($item->present()->name),
trans('mail.item') => htmlspecialchars_decode($item->display_name),
trans('mail.Component_checkout_notification').' by' => $admin->display_name,
trans('admin/consumables/general.remaining') => $item->numRemaining(),
trans('mail.notes') => $note ?: '',
@ -146,7 +146,7 @@ class CheckoutComponentNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Component_checkout_notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -97,7 +97,7 @@ class CheckoutConsumableNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -116,7 +116,7 @@ class CheckoutConsumableNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.Consumable_checkout_notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(htmlspecialchars_decode($item->display_name), '', 'activityTitle')
->fact(trans('mail.Consumable_checkout_notification')." by ", $admin->display_name)
->fact(trans('mail.assigned_to'), $target->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
@ -126,7 +126,7 @@ class CheckoutConsumableNotification extends Notification
$message = trans('mail.Consumable_checkout_notification');
$details = [
trans('mail.assigned_to') => $target->display_name,
trans('mail.item') => htmlspecialchars_decode($item->present()->name),
trans('mail.item') => htmlspecialchars_decode($item->display_name),
trans('mail.Consumable_checkout_notification').' by' => $admin->display_name,
trans('admin/consumables/general.remaining') => $item->numRemaining(),
trans('mail.notes') => $note ?: '',
@ -146,7 +146,7 @@ class CheckoutConsumableNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.Consumable_checkout_notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -95,7 +95,7 @@ class CheckoutLicenseSeatNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});
@ -114,7 +114,7 @@ class CheckoutLicenseSeatNotification extends Notification
->addStartGroupToSection('activityTitle')
->title(trans('mail.License_Checkout_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(htmlspecialchars_decode($item->display_name), '', 'activityTitle')
->fact(trans('mail.License_Checkout_Notification')." by ", $admin->display_name)
->fact(trans('mail.assigned_to'), $target->display_name)
->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count())
@ -124,7 +124,7 @@ class CheckoutLicenseSeatNotification extends Notification
$message = trans('mail.License_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->display_name,
trans('mail.license_for') => htmlspecialchars_decode($item->present()->name),
trans('mail.license_for') => htmlspecialchars_decode($item->display_name),
trans('mail.License_Checkout_Notification').' by' => $admin->display_name,
trans('admin/consumables/general.remaining') => $item->availCount()->count(),
trans('mail.notes') => $note ?: '',
@ -143,7 +143,7 @@ class CheckoutLicenseSeatNotification extends Notification
Card::create()
->header(
'<strong>'.trans('mail.License_Checkout_Notification').'</strong>' ?: '',
htmlspecialchars_decode($item->present()->name) ?: '',
htmlspecialchars_decode($item->display_name) ?: '',
)
->section(
Section::create(

View File

@ -91,7 +91,7 @@ class RequestAssetCancelation extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});

View File

@ -86,7 +86,7 @@ class RequestAssetNotification extends Notification
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
$attachment->title(htmlspecialchars_decode($item->display_name), $item->present()->viewUrl())
->fields($fields)
->content($note);
});

View File

@ -85,6 +85,12 @@ class AppServiceProvider extends ServiceProvider
*/
public function register()
{
if ($this->app->environment('local')) {
$this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
$this->app->register(TelescopeServiceProvider::class);
}
// Only load rollbar if there is a rollbar key and the app is in production
if (($this->app->environment('production')) && (config('logging.channels.rollbar.access_token'))) {
$this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class);

View File

@ -0,0 +1,66 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;
use Laravel\Telescope\TelescopeApplicationServiceProvider;
class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// Telescope::night();
$this->hideSensitiveRequestDetails();
$isLocal = $this->app->environment('local');
Telescope::filter(function (IncomingEntry $entry) use ($isLocal) {
return $isLocal ||
$entry->isReportableException() ||
$entry->isFailedRequest() ||
$entry->isFailedJob() ||
$entry->isScheduledTask() ||
$entry->hasMonitoredTag();
});
}
/**
* Prevent sensitive request details from being logged by Telescope.
*/
protected function hideSensitiveRequestDetails(): void
{
if ($this->app->environment('local')) {
return;
}
Telescope::hideRequestParameters(['_token']);
Telescope::hideRequestHeaders([
'cookie',
'x-csrf-token',
'x-xsrf-token',
]);
}
/**
* Register the Telescope gate.
*
* This gate determines who can access Telescope in NON-LOCAL environments.
*/
protected function gate(): void
{
Gate::define('viewTelescope', function ($user) {
if ($user->isSuperUser()) {
return true;
}
return false;
});
}
}

View File

@ -84,6 +84,7 @@
},
"require-dev": {
"larastan/larastan": "^2.9",
"laravel/telescope": "^5.11",
"mockery/mockery": "^1.4",
"nunomaduro/phpinsights": "^2.11",
"php-mock/php-mock-phpunit": "^2.10",
@ -95,7 +96,8 @@
"extra": {
"laravel": {
"dont-discover": [
"rollbar/rollbar-laravel"
"rollbar/rollbar-laravel",
"laravel/telescope"
]
}
},

71
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "80c3f4268ff9cda7df9ad90a8b11ff50",
"content-hash": "41f2c8e1296de21aaf82d4b1bfbc1800",
"packages": [
{
"name": "alek13/slack",
@ -12883,6 +12883,75 @@
],
"time": "2025-06-10T22:06:33+00:00"
},
{
"name": "laravel/telescope",
"version": "v5.11.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/telescope.git",
"reference": "62e1a21db3db3e7440e9ca02ffa3efce14d6b85e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/telescope/zipball/62e1a21db3db3e7440e9ca02ffa3efce14d6b85e",
"reference": "62e1a21db3db3e7440e9ca02ffa3efce14d6b85e",
"shasum": ""
},
"require": {
"ext-json": "*",
"laravel/framework": "^8.37|^9.0|^10.0|^11.0|^12.0",
"php": "^8.0",
"symfony/console": "^5.3|^6.0|^7.0",
"symfony/var-dumper": "^5.0|^6.0|^7.0"
},
"require-dev": {
"ext-gd": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"laravel/octane": "^1.4|^2.0|dev-develop",
"orchestra/testbench": "^6.40|^7.37|^8.17|^9.0|^10.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.0|^10.5|^11.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Laravel\\Telescope\\TelescopeServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Telescope\\": "src/",
"Laravel\\Telescope\\Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
},
{
"name": "Mohamed Said",
"email": "mohamed@laravel.com"
}
],
"description": "An elegant debug assistant for the Laravel framework.",
"keywords": [
"debugging",
"laravel",
"monitoring"
],
"support": {
"issues": "https://github.com/laravel/telescope/issues",
"source": "https://github.com/laravel/telescope/tree/v5.11.2"
},
"time": "2025-08-16T00:52:51+00:00"
},
{
"name": "league/container",
"version": "5.1.0",

205
config/telescope.php Normal file
View File

@ -0,0 +1,205 @@
<?php
use Laravel\Telescope\Http\Middleware\Authorize;
use Laravel\Telescope\Watchers;
return [
/*
|--------------------------------------------------------------------------
| Telescope Master Switch
|--------------------------------------------------------------------------
|
| This option may be used to disable all Telescope watchers regardless
| of their individual configuration, which simply provides a single
| and convenient way to enable or disable Telescope data storage.
|
*/
'enabled' => env('TELESCOPE_ENABLED', false),
/*
|--------------------------------------------------------------------------
| Telescope Domain
|--------------------------------------------------------------------------
|
| This is the subdomain where Telescope will be accessible from. If the
| setting is null, Telescope will reside under the same domain as the
| application. Otherwise, this value will be used as the subdomain.
|
*/
'domain' => env('TELESCOPE_DOMAIN'),
/*
|--------------------------------------------------------------------------
| Telescope Path
|--------------------------------------------------------------------------
|
| This is the URI path where Telescope will be accessible from. Feel free
| to change this path to anything you like. Note that the URI will not
| affect the paths of its internal API that aren't exposed to users.
|
*/
'path' => env('TELESCOPE_PATH', 'telescope'),
/*
|--------------------------------------------------------------------------
| Telescope Storage Driver
|--------------------------------------------------------------------------
|
| This configuration options determines the storage driver that will
| be used to store Telescope's data. In addition, you may set any
| custom options as needed by the particular driver you choose.
|
*/
'driver' => env('TELESCOPE_DRIVER', 'database'),
'storage' => [
'database' => [
'connection' => env('DB_CONNECTION', 'mysql'),
'chunk' => 1000,
],
],
/*
|--------------------------------------------------------------------------
| Telescope Queue
|--------------------------------------------------------------------------
|
| This configuration options determines the queue connection and queue
| which will be used to process ProcessPendingUpdate jobs. This can
| be changed if you would prefer to use a non-default connection.
|
*/
'queue' => [
'connection' => env('TELESCOPE_QUEUE_CONNECTION'),
'queue' => env('TELESCOPE_QUEUE'),
'delay' => env('TELESCOPE_QUEUE_DELAY', 10),
],
/*
|--------------------------------------------------------------------------
| Telescope Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will be assigned to every Telescope route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/
'middleware' => [
'web',
Authorize::class,
],
/*
|--------------------------------------------------------------------------
| Allowed / Ignored Paths & Commands
|--------------------------------------------------------------------------
|
| The following array lists the URI paths and Artisan commands that will
| not be watched by Telescope. In addition to this list, some Laravel
| commands, like migrations and queue commands, are always ignored.
|
*/
'only_paths' => [
// 'api/*'
],
'ignore_paths' => [
'livewire*',
],
'ignore_commands' => [
//
],
/*
|--------------------------------------------------------------------------
| Telescope Watchers
|--------------------------------------------------------------------------
|
| The following array lists the "watchers" that will be registered with
| Telescope. The watchers gather the application's profile data when
| a request or task is executed. Feel free to customize this list.
|
*/
'watchers' => [
Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true),
Watchers\CacheWatcher::class => [
'enabled' => env('TELESCOPE_CACHE_WATCHER', true),
'hidden' => [],
'ignore' => [],
],
Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true),
Watchers\CommandWatcher::class => [
'enabled' => env('TELESCOPE_COMMAND_WATCHER', true),
'ignore' => [],
],
Watchers\DumpWatcher::class => [
'enabled' => env('TELESCOPE_DUMP_WATCHER', true),
'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false),
],
Watchers\EventWatcher::class => [
'enabled' => env('TELESCOPE_EVENT_WATCHER', true),
'ignore' => [],
],
Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true),
Watchers\GateWatcher::class => [
'enabled' => env('TELESCOPE_GATE_WATCHER', true),
'ignore_abilities' => [],
'ignore_packages' => true,
'ignore_paths' => [],
],
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
Watchers\LogWatcher::class => [
'enabled' => env('TELESCOPE_LOG_WATCHER', true),
'level' => 'error',
],
Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true),
Watchers\ModelWatcher::class => [
'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
'events' => ['eloquent.*'],
'hydrations' => true,
],
Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true),
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'ignore_packages' => true,
'ignore_paths' => [],
'slow' => 100,
],
Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true),
Watchers\RequestWatcher::class => [
'enabled' => env('TELESCOPE_REQUEST_WATCHER', true),
'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64),
'ignore_http_methods' => [],
'ignore_status_codes' => [],
],
Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true),
Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true),
],
];

View File

@ -0,0 +1,70 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Get the migration connection name.
*/
public function getConnection(): ?string
{
return config('telescope.storage.database.connection');
}
/**
* Run the migrations.
*/
public function up(): void
{
$schema = Schema::connection($this->getConnection());
$schema->create('telescope_entries', function (Blueprint $table) {
$table->bigIncrements('sequence');
$table->uuid('uuid');
$table->uuid('batch_id');
$table->string('family_hash')->nullable();
$table->boolean('should_display_on_index')->default(true);
$table->string('type', 20);
$table->longText('content');
$table->dateTime('created_at')->nullable();
$table->unique('uuid');
$table->index('batch_id');
$table->index('family_hash');
$table->index('created_at');
$table->index(['type', 'should_display_on_index']);
});
$schema->create('telescope_entries_tags', function (Blueprint $table) {
$table->uuid('entry_uuid');
$table->string('tag');
$table->primary(['entry_uuid', 'tag']);
$table->index('tag');
$table->foreign('entry_uuid')
->references('uuid')
->on('telescope_entries')
->onDelete('cascade');
});
$schema->create('telescope_monitoring', function (Blueprint $table) {
$table->string('tag')->primary();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$schema = Schema::connection($this->getConnection());
$schema->dropIfExists('telescope_entries_tags');
$schema->dropIfExists('telescope_entries');
$schema->dropIfExists('telescope_monitoring');
}
};

View File

@ -2,7 +2,7 @@
{{-- Page title --}}
@section('title')
{{trans('general.accept', ['asset' => $acceptance->checkoutable->present()->name()])}}
{{trans('general.accept', ['asset' => $acceptance->checkoutable->display_name])}}
@parent
@stop
@ -38,7 +38,7 @@
<div class="panel box box-default">
<div class="box-header with-border">
<h2 class="box-title">
{{$acceptance->checkoutable->present()->name()}}
{{ $acceptance->checkoutable->display_name }}
{{ (($acceptance->checkoutable) && ($acceptance->checkoutable->serial)) ? ' - '.trans('general.serial_number').': '.$acceptance->checkoutable->serial : '' }}
</h2>
</div>

View File

@ -40,7 +40,7 @@
<tr>
<td><input type="checkbox" name="ids[]" value="{{ $asset->id }}" checked="checked"></td>
<td>{{ $asset->id }}</td>
<td>{{ $asset->present()->name() }}</td>
<td>{{ $asset->display_name }}</td>
<td>
@if ($asset->location)
{{ $asset->location->present()->name() }}

View File

@ -39,7 +39,7 @@
<tr>
<td><input type="checkbox" name="ids[]" value="{{ $asset->id }}" checked="checked"></td>
<td>{{ $asset->id }}</td>
<td>{{ $asset->present()->name() }}</td>
<td>{{ $asset->display_name }}</td>
<td>
@if ($asset->location)
{{ $asset->location->name }}

View File

@ -985,6 +985,13 @@ dir="{{ Helper::determineLanguageDirection() }}">
@endif
@endif
@if (isset($user) && ($user->isSuperUser()) && (app()->environment('local')))
<a href="{{ url('telescope') }}" class="btn btn-default btn-xs" rel="noopener">Open Telescope</a>
@endif
@if ($snipeSettings->support_footer!='off')
@if (($snipeSettings->support_footer=='on') || (($snipeSettings->support_footer=='admin') && (Auth::user()->isSuperUser()=='1')))
<a target="_blank" class="btn btn-default btn-xs"

View File

@ -13,7 +13,7 @@ $checkin = Helper::getFormattedDateObject($asset->expected_checkin, 'date');
$assignedToName = $asset->assignedTo ? $asset->assignedTo->present()->fullName : trans('general.unknown_user');
$assignedToRoute = $asset->assignedTo ? route($asset->targetShowRoute().'.show', [$asset->assignedTo->id]) : '';
@endphp
| [{{ $asset->present()->name }}]({{ route('hardware.show', $asset) }}) | @if ($asset->assignedTo) [{{ $assignedToName }}]({{ $assignedToRoute }}) @else {{ $assignedToName }} @endif | {{ $checkin['formatted'] }}
| [{{ $asset->display_name }}]({{ route('hardware.show', $asset) }}) | @if ($asset->assignedTo) [{{ $assignedToName }}]({{ $assignedToRoute }}) @else {{ $assignedToName }} @endif | {{ $checkin['formatted'] }}
@endforeach
@endcomponent

View File

@ -10,7 +10,7 @@ $expires = Helper::getFormattedDateObject($asset->present()->warranty_expires, '
$diff = round(abs(strtotime($asset->present()->warranty_expires) - strtotime(date('Y-m-d')))/86400);
$icon = ($diff <= ($threshold / 2)) ? '🚨' : (($diff <= $threshold) ? '⚠️' : ' ');
@endphp
<tr><td>{{ $icon }} </td><td> <a href="{{ route('hardware.show', $asset->id) }}">{{ $asset->present()->name }}</a><br><small>{{trans('mail.serial').': '.$asset->serial}}</small></td><td> {{ $diff }} {{ trans('mail.Days') }} </td><td> {{ !is_null($expires) ? $expires['formatted'] : '' }} </td><td> {{ ($asset->supplier ? e($asset->supplier->name) : '') }} </td><td> {{ ($asset->assignedTo ? e($asset->assignedTo->present()->display_name) : '') }} </td></tr>
<tr><td>{{ $icon }} </td><td> <a href="{{ route('hardware.show', $asset->id) }}">{{ $asset->display_name }}</a><br><small>{{trans('mail.serial').': '.$asset->serial}}</small></td><td> {{ $diff }} {{ trans('mail.Days') }} </td><td> {{ !is_null($expires) ? $expires['formatted'] : '' }} </td><td> {{ ($asset->supplier ? e($asset->supplier->name) : '') }} </td><td> {{ ($asset->assignedTo ? e($asset->assignedTo->present()->display_name) : '') }} </td></tr>
@endforeach
</table>
@endcomponent

View File

@ -27,12 +27,12 @@ $icon = ($diff <= 7) ? '🚨' : (($diff <= 14) ? '⚠️' : ' ');
<tr>
<td style="vertical-align: top">{{ $icon }}</td>
<td style="vertical-align: top"><a href="{{ route('hardware.show', $asset->id) }}">{{ $asset->present()->name }}</a></td>
<td style="vertical-align: top"><a href="{{ route('hardware.show', $asset->id) }}">{{ $asset->display_name }}</a></td>
<td style="vertical-align: top">{{ $last_audit_date }}</td>
<td style="vertical-align: top">{{ $next_audit_date }}</td>
<td style="vertical-align: top">{{ $diff }}</td>
<td style="vertical-align: top">{{ ($asset->supplier ? e($asset->supplier->name) : '') }}</td>
<td style="vertical-align: top">{{ ($asset->assignedTo ? $asset->assignedTo->present()->name() : '') }}</td>
<td style="vertical-align: top">{{ ($asset->assignedTo ? $asset->display_name : '') }}</td>
<td style="vertical-align: top">{!! nl2br(e($asset->notes)) !!}</td>
</tr>

View File

@ -14,7 +14,7 @@
@foreach($assets as $asset)
<tr>
<td>{{ $asset->present()->name }}</td>
<td>{{ $asset->display_name }}</td>
<td> {{ $asset->asset_tag }} </td>
<td> {{ $asset->serial }} </td>
<td> {{ $asset->model->category->name }}</td>