Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe
2025-04-03 15:41:08 +01:00
9 changed files with 135 additions and 8 deletions
+3 -3
View File
@@ -51,8 +51,7 @@ class PaveIt extends Command
}
// List all the tables in the database so we don't have to worry about missing some as the app grows
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
$tables = Schema::getTables();
$except_tables = [
'oauth_access_tokens',
'oauth_clients',
@@ -74,7 +73,8 @@ class PaveIt extends Command
}
}
foreach ($tables as $table) {
foreach ($tables as $table_obj) {
$table = $table_obj['name'];
if (in_array($table, $except_tables)) {
$this->info($table. ' is SKIPPED.');
} else {
+25 -1
View File
@@ -74,7 +74,7 @@ class CheckoutAssetMail extends Mailable
{
$this->item->load('assetstatus');
$eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : '';
$req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0;
$req_accept = $this->requiresAcceptance();
$fields = [];
// Check if the item has custom fields associated with it
@@ -98,6 +98,7 @@ class CheckoutAssetMail extends Mailable
'accept_url' => $accept_url,
'last_checkout' => $this->last_checkout,
'expected_checkin' => $this->expected_checkin,
'introduction_line' => $this->introductionLine(),
],
);
}
@@ -120,4 +121,27 @@ class CheckoutAssetMail extends Mailable
return trans('mail.unaccepted_asset_reminder');
}
private function introductionLine(): string
{
if ($this->firstTimeSending && $this->requiresAcceptance()) {
return trans('mail.new_item_checked_with_acceptance');
}
if ($this->firstTimeSending && !$this->requiresAcceptance()) {
return trans('mail.new_item_checked');
}
if (!$this->firstTimeSending && $this->requiresAcceptance()) {
return trans('mail.recent_item_checked');
}
// we shouldn't get here but let's send a default message just in case
return trans('new_item_checked');
}
private function requiresAcceptance(): int|bool
{
return method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0;
}
}
+10
View File
@@ -4,6 +4,7 @@ namespace Database\Factories;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\CustomField;
use App\Models\Location;
use App\Models\Statuslabel;
@@ -333,6 +334,15 @@ class AssetFactory extends Factory
});
}
public function doesNotRequireAcceptance()
{
return $this->state(function () {
return [
'model_id' => AssetModel::factory()->doesNotRequireAcceptance(),
];
});
}
public function deleted()
{
return $this->state(function () {
+9
View File
@@ -448,4 +448,13 @@ class AssetModelFactory extends Factory
];
});
}
public function doesNotRequireAcceptance()
{
return $this->state(function () {
return [
'category_id' => Category::factory()->doesNotRequireAcceptance(),
];
});
}
}
+7
View File
@@ -207,4 +207,11 @@ class CategoryFactory extends Factory
'category_type' => 'consumable',
]);
}
public function doesNotRequireAcceptance()
{
return $this->state([
'require_acceptance' => false,
]);
}
}
+3 -1
View File
@@ -66,6 +66,8 @@ return [
'min_QTY' => 'Min QTY',
'name' => 'Name',
'new_item_checked' => 'A new item has been checked out under your name, details are below.',
'new_item_checked_with_acceptance' => 'A new item has been checked out under your name that requires acceptance, details are below.',
'recent_item_checked' => 'An item was recently checked out under your name that requires acceptance, details are below.',
'notes' => 'Notes',
'password' => 'Password',
'password_reset' => 'Password Reset',
@@ -88,7 +90,7 @@ return [
'upcoming-audits' => 'There is :count asset that is coming up for audit within :threshold days.|There are :count assets that are coming up for audit within :threshold days.',
'user' => 'User',
'username' => 'Username',
'unaccepted_asset_reminder' => 'You have Unaccepted Assets.',
'unaccepted_asset_reminder' => 'Reminder: You have Unaccepted Assets.',
'welcome' => 'Welcome :name',
'welcome_to' => 'Welcome to :web!',
'your_assets' => 'View Your Assets',
+1 -1
View File
@@ -102,7 +102,7 @@
<!-- history tab pane -->
<div class="tab-pane fade" id="history">
<div class="table table-responsive">
<div class="table-responsive">
<div class="row">
<div class="col-md-12">
<table
@@ -1,7 +1,7 @@
@component('mail::message')
# {{ trans('mail.hello') }} {{ $target->present()->fullName() }},
{{ trans('mail.new_item_checked') }}
{{ $introduction_line }}
@if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl())
<center><img src="{{ $item->getImageUrl() }}" alt="Asset" style="max-width: 570px;"></center>
@@ -76,4 +76,4 @@
{{ $snipeSettings->site_name }}
@endcomponent
@endcomponent
+75
View File
@@ -0,0 +1,75 @@
<?php
namespace Tests\Unit\Mail;
use App\Mail\CheckoutAssetMail;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\User;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;
class CheckoutAssetMailTest extends TestCase
{
public static function data()
{
yield 'Asset requiring acceptance' => [
function () {
$asset = Asset::factory()->requiresAcceptance()->create();
return [
'asset' => $asset,
'acceptance' => CheckoutAcceptance::factory()->for($asset, 'checkoutable')->create(),
'first_time_sending' => true,
'expected_subject' => 'Asset checked out',
'expected_opening' => 'A new item has been checked out under your name that requires acceptance, details are below.'
];
}
];
yield 'Asset not requiring acceptance' => [
function () {
return [
'asset' => Asset::factory()->doesNotRequireAcceptance()->create(),
'acceptance' => null,
'first_time_sending' => true,
'expected_subject' => 'Asset checked out',
'expected_opening' => 'A new item has been checked out under your name, details are below.'
];
}
];
yield 'Reminder' => [
function () {
return [
'asset' => Asset::factory()->requiresAcceptance()->create(),
'acceptance' => CheckoutAcceptance::factory()->create(),
'first_time_sending' => false,
'expected_subject' => 'Reminder: You have Unaccepted Assets.',
'expected_opening' => 'An item was recently checked out under your name that requires acceptance, details are below.'
];
}
];
}
#[DataProvider('data')]
public function testSubjectLineAndOpening($data)
{
[
'asset' => $asset,
'acceptance' => $acceptance,
'first_time_sending' => $firstTimeSending,
'expected_subject' => $expectedSubject,
'expected_opening' => $expectedOpening,
] = $data();
(new CheckoutAssetMail(
$asset,
User::factory()->create(),
User::factory()->create(),
$acceptance,
'A note goes here',
$firstTimeSending,
))->assertHasSubject($expectedSubject)
->assertSeeInText($expectedOpening);
}
}