Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe
2025-11-20 13:28:00 +00:00
47 changed files with 231 additions and 117 deletions

View File

@@ -13,9 +13,9 @@ use App\Models\Company;
use App\Models\Contracts\Acceptable;
use App\Models\Setting;
use App\Models\User;
use App\Notifications\AcceptanceAssetAcceptedNotification;
use App\Notifications\AcceptanceAssetAcceptedToUserNotification;
use App\Notifications\AcceptanceAssetDeclinedNotification;
use App\Notifications\AcceptanceItemAcceptedNotification;
use App\Notifications\AcceptanceItemAcceptedToUserNotification;
use App\Notifications\AcceptanceItemDeclinedNotification;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
@@ -145,7 +145,7 @@ class AcceptanceController extends Controller
// Get the data array ready for the notifications and PDF generation
$data = [
'item_tag' => $item->asset_tag,
'item_name' => $item->name, // this handles licenses seats, which don't have a 'name' field
'item_name' => $item->display_name, // this handles licenses seats, which don't have a 'name' field
'item_model' => $item->model?->name,
'item_serial' => $item->serial,
'item_status' => $item->assetstatus?->name,
@@ -183,13 +183,13 @@ class AcceptanceController extends Controller
// Add the attachment for the signing user into the $data array
$data['file'] = $pdf_filename;
try {
$assigned_user->notify((new AcceptanceAssetAcceptedToUserNotification($data))->locale($assigned_user->locale));
$assigned_user->notify((new AcceptanceItemAcceptedToUserNotification($data))->locale($assigned_user->locale));
} catch (\Exception $e) {
Log::warning($e);
}
}
try {
$acceptance->notify((new AcceptanceAssetAcceptedNotification($data))->locale(Setting::getSettings()->locale));
$acceptance->notify((new AcceptanceItemAcceptedNotification($data))->locale(Setting::getSettings()->locale));
} catch (\Exception $e) {
Log::warning($e);
}
@@ -204,7 +204,7 @@ class AcceptanceController extends Controller
$acceptance->decline($sig_filename, $request->input('note'));
}
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
$acceptance->notify(new AcceptanceItemDeclinedNotification($data));
Log::debug('New event acceptance.');
event(new CheckoutDeclined($acceptance));
$return_msg = trans('admin/users/message.declined');

View File

@@ -122,17 +122,22 @@ class LicenseSeatsController extends Controller
// check if this update is a checkin operation
// 1. are relevant fields touched at all?
$touched = $licenseSeat->isDirty('assigned_to') || $licenseSeat->isDirty('asset_id');
// 2. are they cleared? if yes then this is a checkin operation
$is_checkin = ($touched && $licenseSeat->assigned_to === null && $licenseSeat->asset_id === null);
$assignmentTouched = $licenseSeat->isDirty('assigned_to') || $licenseSeat->isDirty('asset_id');
$anythingTouched = $licenseSeat->isDirty();
if (! $touched) {
// nothing to update
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
if (! $anythingTouched) {
return response()->json(
Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success'))
);
}
if( $touched && $licenseSeat->unreassignable_seat) {
if( $assignmentTouched && $licenseSeat->unreassignable_seat) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.checkout.unavailable')));
}
// 2. are they cleared? if yes then this is a checkin operation
$is_checkin = ($assignmentTouched && $licenseSeat->assigned_to === null && $licenseSeat->asset_id === null);
$target = null;
// the logging functions expect only one "target". if both asset and user are present in the request,
// we simply let assets take precedence over users...
if ($licenseSeat->isDirty('assigned_to')) {
@@ -142,25 +147,23 @@ class LicenseSeatsController extends Controller
$target = $is_checkin ? $oldAsset : Asset::find($licenseSeat->asset_id);
}
if (is_null($target)){
if ($assignmentTouched && is_null($target)){
return response()->json(Helper::formatStandardApiResponse('error', null, 'Target not found'));
}
if ($licenseSeat->save()) {
if ($is_checkin) {
if(!$licenseSeat->license->reassignable){
$licenseSeat->unreassignable_seat = true;
$licenseSeat->save();
if($assignmentTouched) {
if ($is_checkin) {
if (!$licenseSeat->license->reassignable) {
$licenseSeat->unreassignable_seat = true;
$licenseSeat->save();
}
$licenseSeat->logCheckin($target, $licenseSeat->notes);
} else {
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
$licenseSeat->logCheckout($request->input('notes'), $target);
}
$licenseSeat->logCheckin($target, $licenseSeat->notes);
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
}
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
$licenseSeat->logCheckout($request->input('notes'), $target);
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
}

View File

@@ -1148,7 +1148,9 @@ class ReportsController extends Controller
$query->withTrashed();
}
$itemsForReport = $query->get()->map(fn ($unaccepted) => Checkoutable::fromAcceptance($unaccepted));
$itemsForReport = $query->get()
->filter(fn ($unaccepted) => $unaccepted->checkoutable)
->map(fn ($unaccepted) => Checkoutable::fromAcceptance($unaccepted));
return view('reports/unaccepted_assets', compact('itemsForReport','showDeleted' ));
}
@@ -1288,7 +1290,9 @@ class ReportsController extends Controller
$acceptances->withTrashed();
}
$itemsForReport = $acceptances->get()->map(fn ($unaccepted) => Checkoutable::fromAcceptance($unaccepted));
$itemsForReport = $acceptances->get()
->filter(fn ($unaccepted) => $unaccepted->checkoutable)
->map(fn ($unaccepted) => Checkoutable::fromAcceptance($unaccepted));
$rows = [];

18
app/Mail/BaseMailable.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace App\Mail;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Headers;
class BaseMailable extends Mailable
{
public function headers(): Headers
{
return new Headers(
text: [
'X-Auto-Response-Suppress' => 'OOF, DR, RN, NRN, AutoReply',
'X-System-Sender' => 'Snipe-IT',
]
);
}
}

View File

@@ -6,14 +6,12 @@ use App\Models\Accessory;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckinAccessoryMail extends Mailable
class CheckinAccessoryMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -7,15 +7,13 @@ use App\Models\Asset;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Queue\SerializesModels;
class CheckinAssetMail extends Mailable
class CheckinAssetMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -7,14 +7,12 @@ use App\Models\Component;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckinComponentMail extends Mailable
class CheckinComponentMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -6,14 +6,12 @@ use App\Models\LicenseSeat;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckinLicenseMail extends Mailable
class CheckinLicenseMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -5,13 +5,11 @@ namespace App\Mail;
use App\Models\CheckoutAcceptance;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckoutAcceptanceResponseMail extends Mailable
class CheckoutAcceptanceResponseMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -8,15 +8,13 @@ use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class CheckoutAccessoryMail extends Mailable
class CheckoutAccessoryMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -8,8 +8,6 @@ use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
@@ -17,7 +15,7 @@ use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Queue\SerializesModels;
class CheckoutAssetMail extends Mailable
class CheckoutAssetMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -6,13 +6,12 @@ use App\Models\Component;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckoutComponentMail extends Mailable
class CheckoutComponentMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -6,15 +6,12 @@ use App\Models\Consumable;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class CheckoutConsumableMail extends Mailable
class CheckoutConsumableMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -7,14 +7,12 @@ use App\Models\LicenseSeat;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CheckoutLicenseMail extends Mailable
class CheckoutLicenseMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -3,14 +3,12 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class ExpiringAssetsMail extends Mailable
class ExpiringAssetsMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -3,14 +3,12 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class ExpiringLicenseMail extends Mailable
class ExpiringLicenseMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -3,14 +3,12 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class SendUpcomingAuditMail extends Mailable
class SendUpcomingAuditMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -3,14 +3,12 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class UnacceptedAssetReminderMail extends Mailable
class UnacceptedAssetReminderMail extends BaseMailable
{
use Queueable, SerializesModels;

View File

@@ -26,7 +26,7 @@ class Checkoutable
$acceptance = $unaccepted;
$assignee = $acceptance->assignedTo;
$company = $unaccepted_row->company ? optional($unaccepted_row->company)->present()->nameUrl() : '';
$company = $unaccepted_row?->company?->present()?->nameUrl() ?? '';
$category = $model = $name = $tag = '';
$type = $acceptance->checkoutable_item_type ?? '';
@@ -70,10 +70,10 @@ class Checkoutable
acceptance: $acceptance,
assignee: $assignee,
//plain text for CSVs
plain_text_category: ($unaccepted_row->model?->category?->name ?? $unaccepted_row->license->category?->name ?? $unaccepted_row->category?->name ?? ''),
plain_text_model: ($unaccepted_row->model?->name ?? $unaccepted_row->model_number ?? ''),
plain_text_name: ($unaccepted_row->name ?? $unaccepted_row->license?->name ?? ''),
plain_text_company: ($unaccepted_row->company)->name ?? $unaccepted_row->license->company?->name ?? '',
plain_text_category: $unaccepted_row?->model?->category?->name ?? $unaccepted_row?->license?->category?->name ?? $unaccepted_row?->category?->name ?? '',
plain_text_model: $unaccepted_row?->model?->name ?? $unaccepted_row?->model_number ?? '',
plain_text_name: $unaccepted_row?->name ?? $unaccepted_row?->license?->name ?? '',
plain_text_company: $unaccepted_row?->company->name ?? $unaccepted_row?->license?->company?->name ?? '',
);
}
}

View File

@@ -3,15 +3,14 @@
namespace App\Notifications;
use AllowDynamicProperties;
use App\Helpers\Helper;
use App\Models\Setting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties] class AcceptanceAssetAcceptedNotification extends Notification
#[AllowDynamicProperties]
class AcceptanceItemAcceptedNotification extends Notification
{
use Queueable;
@@ -77,9 +76,14 @@ use Illuminate\Notifications\Notification;
'assigned_to' => $this->assigned_to,
'company_name' => $this->company_name,
'qty' => $this->qty,
'intro_text' => trans('mail.acceptance_asset_accepted'),
'intro_text' => trans('mail.acceptance_accepted_greeting', ['user' => $this->assigned_to, 'item' => $this->item_name]),
])
->subject(trans('mail.acceptance_asset_accepted'));
->subject('✅ '.trans('mail.acceptance_accepted', ['user' => $this->assigned_to, 'item' => $this->item_name]))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -8,8 +8,10 @@ use App\Models\Setting;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties] class AcceptanceAssetAcceptedToUserNotification extends Notification
#[AllowDynamicProperties]
class AcceptanceItemAcceptedToUserNotification extends Notification
{
use Queueable;
@@ -73,7 +75,12 @@ use Illuminate\Notifications\Notification;
'intro_text' => trans_choice('mail.acceptance_asset_accepted_to_user', $this->qty, ['qty' => $this->qty, 'site_name' => $this->settings->site_name]),
])
->attach($pdf_path)
->subject(trans_choice('mail.acceptance_asset_accepted_to_user', $this->qty, ['qty' => $this->qty, 'site_name' => $this->settings->site_name]));
->subject('✅ '. trans_choice('mail.acceptance_asset_accepted_to_user', $this->qty, ['qty' => $this->qty, 'site_name' => $this->settings->site_name]))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -2,15 +2,14 @@
namespace App\Notifications;
use App\Helpers\Helper;
use App\Models\Setting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
class AcceptanceAssetDeclinedNotification extends Notification
#[AllowDynamicProperties]
class AcceptanceItemDeclinedNotification extends Notification
{
use Queueable;
@@ -21,6 +20,7 @@ class AcceptanceAssetDeclinedNotification extends Notification
*/
public function __construct($params)
{
$this->item_name = $params['item_name'];
$this->item_tag = $params['item_tag'];
$this->item_model = $params['item_model'];
$this->item_serial = $params['item_serial'];
@@ -64,6 +64,7 @@ class AcceptanceAssetDeclinedNotification extends Notification
$message = (new MailMessage)->markdown('notifications.markdown.asset-acceptance',
[
'item_tag' => $this->item_tag,
'item_name' => $this->item_name,
'item_model' => $this->item_model,
'item_serial' => $this->item_serial,
'item_status' => $this->item_status,
@@ -73,9 +74,14 @@ class AcceptanceAssetDeclinedNotification extends Notification
'company_name' => $this->company_name,
'qty' => $this->qty,
'admin' => $this->admin,
'intro_text' => trans('mail.acceptance_asset_declined'),
'intro_text' => trans('mail.acceptance_declined_greeting'),
])
->subject(trans('mail.acceptance_asset_declined'));
->subject('⚠️ '.trans('mail.acceptance_declined', ['user' => $this->assigned_to, 'item' => $this->item_name]))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -12,8 +12,10 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties] class AuditNotification extends Notification
#[AllowDynamicProperties]
class AuditNotification extends Notification
{
use Queueable;
/**

View File

@@ -18,8 +18,8 @@ use NotificationChannels\GoogleChat\Section;
use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Illuminate\Support\Facades\Log;
#[AllowDynamicProperties]
class CheckinAccessoryNotification extends Notification
{
use Queueable;

View File

@@ -20,6 +20,7 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Illuminate\Support\Facades\Log;
#[AllowDynamicProperties]
class CheckinAssetNotification extends Notification
{
use Queueable;

View File

@@ -18,6 +18,7 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
#[AllowDynamicProperties]
class CheckinComponentNotification extends Notification
{
use Queueable;

View File

@@ -19,6 +19,7 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
#[AllowDynamicProperties]
class CheckinLicenseSeatNotification extends Notification
{
use Queueable;

View File

@@ -18,7 +18,9 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class CheckoutAccessoryNotification extends Notification
{
use Queueable;
@@ -210,6 +212,11 @@ class CheckoutAccessoryNotification extends Notification
'accept_url' => $accept_url,
'checkout_qty' => $this->checkout_qty,
])
->subject(trans('mail.Confirm_accessory_delivery'));
->subject(trans('mail.Confirm_accessory_delivery'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
}
}

View File

@@ -25,6 +25,7 @@ use Illuminate\Support\Facades\Log;
use Osama\LaravelTeamsNotification\Logging\TeamsLoggingChannel;
use Osama\LaravelTeamsNotification\TeamsNotification;
#[AllowDynamicProperties]
class CheckoutAssetNotification extends Notification
{
use Queueable;

View File

@@ -20,6 +20,7 @@ use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
#[AllowDynamicProperties]
class CheckoutComponentNotification extends Notification
{
use Queueable;

View File

@@ -20,6 +20,7 @@ use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Illuminate\Support\Facades\Log;
#[AllowDynamicProperties]
class CheckoutConsumableNotification extends Notification
{
use Queueable;

View File

@@ -19,6 +19,7 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
#[AllowDynamicProperties]
class CheckoutLicenseSeatNotification extends Notification
{
use Queueable;

View File

@@ -5,7 +5,9 @@ namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class CurrentInventory extends Notification
{
use Queueable;
@@ -45,7 +47,12 @@ class CurrentInventory extends Notification
'licenses' => $this->user->licenses,
'consumables' => $this->user->consumables,
])
->subject(trans('mail.inventory_report'));
->subject(trans('mail.inventory_report'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -5,7 +5,9 @@ namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class ExpectedCheckinAdminNotification extends Notification
{
use Queueable;
@@ -48,7 +50,12 @@ class ExpectedCheckinAdminNotification extends Notification
[
'assets' => $this->assets,
])
->subject(trans('mail.Expected_Checkin_Report'));
->subject('⏰'.trans('mail.Expected_Checkin_Report'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -7,7 +7,9 @@ use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class ExpectedCheckinNotification extends Notification
{
use Queueable;
@@ -58,7 +60,12 @@ class ExpectedCheckinNotification extends Notification
'serial' => $this->params->serial,
'asset_tag' => $this->params->asset_tag,
])
->subject(($today > $this->params->expected_checkin) ? trans('mail.Expected_Checkin_Notification_Pastdue', ['name' => $this->params->display_name]) : trans('mail.Expected_Checkin_Notification', ['name' => $this->params->display_name]));
->subject('⏰'. ($today > $this->params->expected_checkin) ? trans('mail.Expected_Checkin_Notification_Pastdue', ['name' => $this->params->display_name]) : trans('mail.Expected_Checkin_Notification', ['name' => $this->params->display_name]))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -5,7 +5,9 @@ namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class ExpiringAssetsNotification extends Notification
{
use Queueable;
@@ -51,7 +53,12 @@ class ExpiringAssetsNotification extends Notification
'assets' => $this->assets,
'threshold' => $this->threshold,
])
->subject(trans('mail.Expiring_Assets_Report'));
->subject('⏰'.trans('mail.Expiring_Assets_Report'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -5,7 +5,9 @@ namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class ExpiringLicenseNotification extends Notification
{
use Queueable;
@@ -52,7 +54,12 @@ class ExpiringLicenseNotification extends Notification
'licenses' => $this->licenses,
'threshold' => $this->threshold,
])
->subject(trans('mail.Expiring_Licenses_Report'));
->subject('⏰'.trans('mail.Expiring_Licenses_Report'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -5,7 +5,9 @@ namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class FirstAdminNotification extends Notification
{
use Queueable;
@@ -45,7 +47,12 @@ class FirstAdminNotification extends Notification
public function toMail()
{
return (new MailMessage)
->subject(trans('mail.welcome', ['name' => $this->_data['first_name'].' '.$this->_data['last_name']]))
->markdown('notifications.FirstAdmin', $this->_data);
->subject('👋 '.trans('mail.welcome', ['name' => $this->_data['first_name'].' '.$this->_data['last_name']]))
->markdown('notifications.FirstAdmin', $this->_data)
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
}
}

View File

@@ -6,6 +6,7 @@ use AllowDynamicProperties;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class InventoryAlert extends Notification
@@ -52,7 +53,12 @@ class InventoryAlert extends Notification
'threshold' => $this->threshold,
]
)
->subject(trans('mail.Low_Inventory_Report'));
->subject('⚠️ '.trans('mail.Low_Inventory_Report'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -2,11 +2,12 @@
namespace App\Notifications;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class MailTest extends Notification
{
use Queueable;
@@ -39,7 +40,12 @@ class MailTest extends Notification
public function toMail()
{
return (new MailMessage)
->subject(trans('mail.test_email'))
->markdown('notifications.Test');
->subject('👋 '.trans('mail.test_email'))
->markdown('notifications.Test')
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
}
}

View File

@@ -8,7 +8,9 @@ use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class RequestAssetCancelation extends Notification
{
/**
@@ -124,7 +126,12 @@ class RequestAssetCancelation extends Notification
'expected_checkin' => $this->expected_checkin,
'intro_text' => trans('mail.a_user_canceled'),
])
->subject(trans('Item Request Canceled'));
->subject('⚠️ '.trans('general.request_canceled'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -7,7 +7,9 @@ use App\Models\Setting;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class RequestAssetNotification extends Notification
{
/**
@@ -118,7 +120,12 @@ class RequestAssetNotification extends Notification
'intro_text' => trans('mail.a_user_requested'),
'qty' => $this->item_quantity,
])
->subject(trans('mail.Item_Requested'));
->subject('👀 '.trans('mail.Item_Requested'))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -7,7 +7,9 @@ use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class SendUpcomingAuditNotification extends Notification
{
use Queueable;
@@ -45,7 +47,12 @@ class SendUpcomingAuditNotification extends Notification
'assets' => $this->assets,
'threshold' => $this->threshold,
])
->subject(trans_choice('mail.upcoming-audits', $this->assets->count(), ['count' => $this->assets->count(), 'threshold' => $this->threshold]));
->subject('⏰'.trans_choice('mail.upcoming-audits', $this->assets->count(), ['count' => $this->assets->count(), 'threshold' => $this->threshold]))
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
return $message;
}

View File

@@ -7,7 +7,9 @@ use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Password;
use App\Models\User;
use Symfony\Component\Mime\Email;
#[AllowDynamicProperties]
class WelcomeNotification extends Notification
{
use Queueable;
@@ -43,7 +45,12 @@ class WelcomeNotification extends Notification
{
return (new MailMessage())
->subject(trans('mail.welcome', ['name' => $this->user->first_name.' '.$this->user->last_name]))
->markdown('notifications.Welcome', $this->user->toArray());
->subject('👋 '.trans('mail.welcome', ['name' => $this->user->first_name.' '.$this->user->last_name]))
->markdown('notifications.Welcome', $this->user->toArray())
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-System-Sender', 'Snipe-IT'
);
});
}
}

View File

@@ -34,8 +34,10 @@ return [
'a_user_canceled' => 'A user has canceled an item request on the website',
'a_user_requested' => 'A user has requested an item on the website',
'acceptance_asset_accepted_to_user' => 'You have accepted an item assigned to you by :site_name|You have accepted :qty items assigned to you by :site_name',
'acceptance_asset_accepted' => 'A user has accepted an item',
'acceptance_asset_declined' => 'A user has declined an item',
'acceptance_accepted' => 'ACCEPTED: :user has accepted :item',
'acceptance_declined' => 'DECLINED: :user has declined :item',
'acceptance_accepted_greeting' => ':user has accepted an item:',
'acceptance_declined_greeting' => ':user has declined an item',
'send_pdf_copy' => 'Send a copy of this acceptance to my email address',
'accessory_name' => 'Accessory Name',
'additional_notes' => 'Additional Notes',

View File

@@ -1,13 +1,13 @@
@component('mail::message')
# {{ trans('mail.hello') }},
{{ $intro_text }}.
{{ $intro_text }}
@component('mail::table')
| | |
| ------------- | ------------- |
@if (isset($item_name))
| **{{ trans('general.asset_name') }}** | {{ $item_name }} |
| **{{ trans('general.item_name') }}** | {{ $item_name }} |
@endif
| **{{ trans('mail.user') }}** | {{ $assigned_to }} |
@if (isset($user->location))

View File

@@ -7,8 +7,8 @@ use App\Models\AccessoryCheckout;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\User;
use App\Notifications\AcceptanceAssetAcceptedNotification;
use App\Notifications\AcceptanceAssetDeclinedNotification;
use App\Notifications\AcceptanceItemAcceptedNotification;
use App\Notifications\AcceptanceItemDeclinedNotification;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
@@ -36,7 +36,7 @@ class AccessoryAcceptanceTest extends TestCase
Notification::assertSentTo(
$acceptance,
function (AcceptanceAssetAcceptedNotification $notification) use ($acceptance) {
function (AcceptanceItemAcceptedNotification $notification) use ($acceptance) {
$this->assertStringContainsString(
$acceptance->assignedTo->present()->fullName,
$notification->toMail()->render()
@@ -69,7 +69,7 @@ class AccessoryAcceptanceTest extends TestCase
Notification::assertSentTo(
$acceptance,
function (AcceptanceAssetDeclinedNotification $notification) use ($acceptance) {
function (AcceptanceItemDeclinedNotification $notification) use ($acceptance) {
$this->assertStringContainsString(
$acceptance->assignedTo->present()->fullName,
$notification->toMail($acceptance)->render()