Merge branch 'develop' into fix_action_date

This commit is contained in:
snipe
2025-06-06 17:18:27 +01:00
committed by GitHub
1991 changed files with 37146 additions and 10672 deletions

View File

@@ -3,6 +3,7 @@
namespace Database\Factories;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\Category;
use App\Models\Location;
use App\Models\Manufacturer;
@@ -170,4 +171,30 @@ class AccessoryFactory extends Factory
}
});
}
public function checkedOutToAsset(Asset $asset = null)
{
return $this->afterCreating(function (Accessory $accessory) use ($asset) {
$accessory->checkouts()->create([
'accessory_id' => $accessory->id,
'created_at' => Carbon::now(),
'created_by' => 1,
'assigned_to' => $asset->id ?? Asset::factory()->create()->id,
'assigned_type' => Asset::class,
]);
});
}
public function checkedOutToLocation(Location $location = null)
{
return $this->afterCreating(function (Accessory $accessory) use ($location) {
$accessory->checkouts()->create([
'accessory_id' => $accessory->id,
'created_at' => Carbon::now(),
'created_by' => 1,
'assigned_to' => $location->id ?? Location::factory()->create()->id,
'assigned_type' => Location::class,
]);
});
}
}

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 () {
@@ -347,12 +357,22 @@ class AssetFactory extends Factory
public function requestable()
{
return $this->state(['requestable' => true]);
$id = Statuslabel::factory()->create([
'archived' => false,
'deployable' => true,
'pending' => true,
])->id;
return $this->state(['status_id' => $id, 'requestable' => true]);
}
public function nonrequestable()
{
return $this->state(['requestable' => false]);
$id = Statuslabel::factory()->create([
'archived' => true,
'deployable' => false,
'pending' => false,
])->id;
return $this->state(['status_id' => $id, 'requestable' => false]);
}
public function noPurchaseOrEolDate()

View File

@@ -448,4 +448,13 @@ class AssetModelFactory extends Factory
];
});
}
public function doesNotRequireAcceptance()
{
return $this->state(function () {
return [
'category_id' => Category::factory()->doesNotRequireAcceptance(),
];
});
}
}

View File

@@ -25,10 +25,10 @@ class CategoryFactory extends Factory
return [
'name' => $this->faker->catchPhrase(),
'category_type' => 'asset',
'checkin_email' => $this->faker->boolean(),
'checkin_email' => true,
'eula_text' => $this->faker->paragraph(),
'require_acceptance' => false,
'use_default_eula' => $this->faker->boolean(),
'use_default_eula' => false,
'created_by' => User::factory()->superuser(),
'notes' => 'Created by DB seeder',
];
@@ -207,4 +207,11 @@ class CategoryFactory extends Factory
'category_type' => 'consumable',
]);
}
public function doesNotRequireAcceptance()
{
return $this->state([
'require_acceptance' => false,
]);
}
}

View File

@@ -165,4 +165,72 @@ class ImportFactory extends Factory
});
}
/**
* Create a supplier import type.
*
* @return static
*/
public function suppliers()
{
return $this->state(function (array $attributes) {
$fileBuilder = Importing\SuppliersImportFileBuilder::new();
$attributes['name'] = "Supplier {$attributes['name']}";
$attributes['import_type'] = 'supplier';
$attributes['header_row'] = $fileBuilder->toCsv()[0];
$attributes['first_row'] = $fileBuilder->firstRow();
return $attributes;
});
}
/**
* Create an supplier import type.
*
* @return static
*/
public function locations()
{
return $this->state(function (array $attributes) {
$fileBuilder = Importing\SuppliersImportFileBuilder::new();
$attributes['name'] = "Location {$attributes['name']}";
$attributes['import_type'] = 'location';
$attributes['header_row'] = $fileBuilder->toCsv()[0];
$attributes['first_row'] = $fileBuilder->firstRow();
return $attributes;
});
}
/**
* Create a supplier import type.
*
* @return static
*/
public function manufacturers()
{
return $this->state(function (array $attributes) {
$fileBuilder = Importing\ManufacturersImportFileBuilder::new();
$attributes['name'] = "Manufacturer {$attributes['name']}";
$attributes['import_type'] = 'manufacturer';
$attributes['header_row'] = $fileBuilder->toCsv()[0];
$attributes['first_row'] = $fileBuilder->firstRow();
return $attributes;
});
}
public function categories()
{
return $this->state(function (array $attributes) {
$fileBuilder = Importing\CategoriesImportFileBuilder::new();
$attributes['name'] = "Category {$attributes['name']}";
$attributes['import_type'] = 'category';
$attributes['header_row'] = $fileBuilder->toCsv()[0];
$attributes['first_row'] = $fileBuilder->firstRow();
return $attributes;
});
}
}

View File

@@ -166,4 +166,49 @@ class ManufacturerFactory extends Factory
];
});
}
public function samsung()
{
return $this->state(function () {
return [
'name' => 'Samsung',
'url' => 'https://www.samsung.com',
'support_url' => 'https://www.samsung.com/support/',
'image' => 'samsung.png',
];
});
}
public function google()
{
return $this->state(function () {
return [
'name' => 'Google',
'url' => 'https://www.google.com',
'image' => 'google.webp',
];
});
}
public function huawei()
{
return $this->state(function () {
return [
'name' => 'Huawei',
'url' => 'https://consumer.huawei.com/',
'image' => 'huawei.webp',
];
});
}
public function sony()
{
return $this->state(function () {
return [
'name' => 'Sony',
'url' => 'https://electronics.sony.com',
'image' => 'sony.png',
];
});
}
}

View File

@@ -150,6 +150,11 @@ class UserFactory extends Factory
return $this->appendPermission(['models.delete' => '1']);
}
public function viewAssetModels()
{
return $this->appendPermission(['models.view' => '1']);
}
public function viewAccessories()
{
return $this->appendPermission(['accessories.view' => '1']);
@@ -290,6 +295,11 @@ class UserFactory extends Factory
return $this->appendPermission(['companies.delete' => '1']);
}
public function editCompanies()
{
return $this->appendPermission(['companies.edit' => '1']);
}
public function viewUsers()
{
return $this->appendPermission(['users.view' => '1']);
@@ -360,6 +370,11 @@ class UserFactory extends Factory
return $this->appendPermission(['kits.delete' => '1']);
}
public function viewPredefinedKits()
{
return $this->appendPermission(['kits.view' => '1']);
}
public function deleteStatusLabels()
{
return $this->appendPermission(['statuslabels.delete' => '1']);
@@ -370,6 +385,12 @@ class UserFactory extends Factory
return $this->appendPermission(['suppliers.delete' => '1']);
}
public function auditAssets()
{
return $this->appendPermission(['assets.audit' => '1']);
}
private function appendPermission(array $permission)
{
return $this->state(function ($currentState) use ($permission) {

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddCompanyIdToLocations extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('locations', function (Blueprint $table) {
$table->integer('company_id')->unsigned()->nullable();
$table->index(['company_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('locations', function (Blueprint $table) {
$table->dropIndex(['company_id']);
$table->dropColumn('company_id');
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddScopeLocationsSetting extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('scope_locations_fmcs')->default('0')->after('full_multiple_companies_support');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('scope_locations_fmcs');
});
}
}

View File

@@ -26,7 +26,7 @@ class CreateReportTemplatesTable extends Migration
* for the systems that had successfully run the migration:
* 2025_01_06_210534_change_report_templates_options_to_column_text_field.
*
* https://github.com/snipe/snipe-it/issues/16015
* https://github.com/grokability/snipe-it/issues/16015
*/
$table->text('options');

View File

@@ -17,7 +17,7 @@ return new class extends Migration {
* This migration definitively changes it to a text column
* for the systems that had successfully run the migration.
*
* https://github.com/snipe/snipe-it/issues/16015
* https://github.com/grokability/snipe-it/issues/16015
*/
if (Schema::hasTable('report_templates') && Schema::hasColumn('report_templates', 'options')) {
Schema::table('report_templates', function (Blueprint $table) {

View File

@@ -0,0 +1,30 @@
<?php
use App\Models\Consumable;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::table('action_logs')
->where([
'action_type' => 'checkin from',
'note' => 'Bulk checkin items',
'item_type' => Consumable::class,
])
->delete();
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// nothing to do here...
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->char('acceptance_pdf_logo')->after('label_logo')->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('acceptance_pdf_logo');
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('custom_fields', function (Blueprint $table) {
$table->boolean('display_audit')->default(0);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('custom_fields', function (Blueprint $table) {
$table->dropColumn('display_audit');
});
}
};

View File

@@ -0,0 +1,21 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->unsignedInteger('label2_empty_row_count')->default(0)->after('label2_fields');
});
}
public function down(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('label2_empty_row_count');
});
}
};

View File

@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
$settings = DB::table('settings')->first();
if ($settings) {
/** If webhook settings were cleared via the integration settings page,
* the webhook_selected was cleared as well when it should have reset to "slack".
*/
if (
empty($settings->webhook_selected) &&
(empty($settings->webhook_botname) && empty($settings->webhook_channel) && empty($settings->webhook_endpoint))
) {
DB::table('settings')->update(['webhook_selected' => 'slack']);
}
/** If webhook settings were cleared via the integration settings page,
* then slack settings were re-added; then webhook_selected was not being set to "slack" as needed.
*/
if (str_contains($settings->webhook_endpoint, 'slack.com')) {
DB::table('settings')->update(['webhook_selected' => 'slack']);
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('admin_cc_always')->after('admin_cc_email')->default(1);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('admin_cc_always');
});
}
};

View File

@@ -0,0 +1,23 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::table('assets')->whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('action_logs', function (Blueprint $table) {
$table->index('deleted_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('action_logs', function (Blueprint $table) {
$table->dropIndex('deleted_at');
});
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('asset_maintenances', function (Blueprint $table) {
$table->integer('supplier_id')->nullable()->default(null)->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};

View File

@@ -27,6 +27,10 @@ class ManufacturerSeeder extends Seeder
Manufacturer::factory()->count(1)->adobe()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->avery()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->crucial()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->samsung()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->google()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->huawei()->create(['created_by' => $admin->id]);
Manufacturer::factory()->count(1)->sony()->create(['created_by' => $admin->id]);
$src = public_path('/img/demo/manufacturers/');
$dst = 'manufacturers'.'/';