Improved audit email

This commit is contained in:
snipe
2025-10-07 14:08:33 +01:00
parent 1a3b22171c
commit 1735fb6bed
4 changed files with 103 additions and 40 deletions
@@ -47,7 +47,7 @@ class SendUpcomingAuditReport extends Command
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval);
$assets = Asset::whereNull('deleted_at')->dueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
$assets = Asset::whereNull('deleted_at')->dueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'asc')->get();
$this->info($assets->count() . ' assets must be audited in on or before ' . $interval_date . ' is deadline');
@@ -61,6 +61,28 @@ class SendUpcomingAuditReport extends Command
$this->info('Sending Admin SendUpcomingAuditNotification to: ' . $settings->alert_email);
Mail::to($recipients)->send(new SendUpcomingAuditMail($assets, $settings->audit_warning_days));
$this->table(
[
trans('general.id'),
trans('general.name'),
trans('general.last_audit'),
trans('general.next_audit_date'),
trans('mail.Days'),
trans('mail.supplier'),
trans('mail.assigned_to'),
],
$assets->map(fn($item) => [
trans('general.id') => $item->id,
trans('general.name') => $item->display_name,
trans('general.last_audit') => $item->last_audit_formatted_date,
trans('general.next_audit_date') => $item->next_audit_formatted_date,
trans('mail.Days') => round($item->next_audit_diff_in_days),
trans('mail.supplier') => $item->supplier ? $item->supplier->name : '',
trans('mail.assigned_to') => $item->assignedTo ? $item->assignedTo->display_name : '',
])
);
}
}
+49
View File
@@ -308,6 +308,54 @@ class Asset extends Depreciable
}
protected function lastAuditFormattedDate(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => Helper::getFormattedDateObject($this->last_audit_date, 'datetime', false)
);
}
protected function lastAuditDiff(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $this->warrantyExpires ? round((Carbon::now()->diffInDays($this->warrantyExpires))) : null,
);
}
protected function lastAuditDiffForHumans(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['last_audit_date'] ? Carbon::parse($attributes['last_audit_date'])->diffForHumans() : null,
);
}
protected function nextAuditFormattedDate(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => Helper::getFormattedDateObject($this->next_audit_date, 'date', false)
);
}
protected function nextAuditDiffInDays(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['next_audit_date'] ? Carbon::now()->diffInDays($attributes['next_audit_date']) : null,
);
}
protected function nextAuditDiffForHumans(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['next_audit_date'] ? Carbon::parse($attributes['next_audit_date'])->diffForHumans() : null,
);
}
protected function eolDate(): Attribute
{
@@ -326,6 +374,7 @@ class Asset extends Depreciable
}
protected function eolFormattedDate(): Attribute
{
return Attribute:: make(
+3 -3
View File
@@ -32,7 +32,7 @@ class SnipeModel extends Model
protected function expiresDiffInDays(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['expiration_date'] ? Carbon::now()->diffInDays($attributes['expiration_date']) : null,
get: fn(mixed $value, array $attributes) => in_array('expiration_date', $attributes) ? Carbon::now()->diffInDays($attributes['expiration_date']) : null,
);
}
@@ -40,14 +40,14 @@ class SnipeModel extends Model
protected function expiresDiffForHumans(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['expiration_date'] ? Carbon::parse($attributes['expiration_date'])->diffForHumans() : null,
get: fn(mixed $value, array $attributes) => in_array('expiration_date', $attributes) ? Carbon::parse($attributes['expiration_date'])->diffForHumans() : null,
);
}
protected function expiresFormattedDate(): Attribute
{
return Attribute:: make(
get: fn(mixed $value, array $attributes) => $attributes['expiration_date'] ? Helper::getFormattedDateObject($attributes['expiration_date'], 'date', false) : null,
get: fn(mixed $value, array $attributes) => in_array('expiration_date', $attributes) ? Helper::getFormattedDateObject($attributes['expiration_date'], 'date', false) : null,
);
}
@@ -1,43 +1,35 @@
@component('mail::message')
### {{ trans_choice('mail.upcoming-audits', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold]) }}
<table style="width:100%">
<thead>
<tr>
<th style="vertical-align: top"> </th>
<th style="vertical-align: top">{{ trans('mail.name') }}</th>
<th style="vertical-align: top">{{ trans('general.last_audit') }}</th>
<th style="vertical-align: top">{{ trans('general.next_audit_date') }}</th>
<th style="vertical-align: top">{{ trans('mail.Days') }}</th>
<th style="vertical-align: top">{{ trans('mail.supplier') }}</th>
<th style="vertical-align: top">{{ trans('mail.assigned_to') }}</th>
<th style="vertical-align: top">{{ trans('general.notes') }}</th>
</tr>
{{ trans_choice('mail.upcoming-audits', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold]) }}
<x-mail::table>
| | | |
| ------------- | ------------- | ------------- |
@foreach ($assets as $asset)
@php
$next_audit_date = Helper::getFormattedDateObject($asset->next_audit_date, 'date', false);
$last_audit_date = Helper::getFormattedDateObject($asset->last_audit_date, 'date', false);
$diff = (int) Carbon::parse(Carbon::now())->diffInDays($asset->next_audit_date, true);
$icon = ($diff <= 7) ? '🚨' : (($diff <= 14) ? '⚠️' : ' ');
@endphp
<tr>
<td style="vertical-align: top">{{ $icon }}</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->display_name : '') }}</td>
<td style="vertical-align: top">{!! nl2br(e($asset->notes)) !!}</td>
</tr>
| {{ ($asset->next_audit_diff_in_days <= 7) ? '🚨' : (($asset->next_audit_diff_in_days <= 14) ? '⚠️' : '⚠️') }} **{{ trans('mail.name') }}** | <a href="{{ route('hardware.show', $asset->id) }}">{{ $asset->display_name }}</a> |
@if ($asset->serial)
| **{{ trans('general.serial_number') }}** | {{ $asset->serial }} |
@endif
@if ($asset->purchase_date)
| **{{ trans('general.purchase_date') }}** | {{ $asset->purchase_date_formatted }} |
@endif
@if ($asset->last_audit_date)
| **{{ trans('general.last_audit') }}** | {{ $asset->last_audit_formatted_date }} ({{ $asset->last_audit_diff_for_humans }}) |
@endif
@if ($asset->next_audit_date)
| **{{ trans('general.next_audit_date') }}** | {{ $asset->next_audit_formatted_date }} ({{ $asset->next_audit_diff_for_humans }}) |
@endif
@if ($asset->supplier)
| **{{ trans('mail.supplier') }}** | {{ ($asset->supplier ? e($asset->supplier->name) : '') }} |
@endif
@if ($asset->assignedTo)
| **{{ trans('mail.assigned_to') }}** | {{ e($asset->assignedTo->present()->display_name) }} |
@endif
| <hr> | <hr> |
@endforeach
</table>
</x-mail::table>
<x-mail::button :url="route('assets.audit.due')">
{{ trans_choice('general.audit_due_days', $threshold, ['days' => $threshold]) }}
</x-mail::button>
@endcomponent