changes 0328092025

This commit is contained in:
Simon Pocrnjič
2025-09-28 22:36:47 +02:00
parent b40ee9dcde
commit 7e8e0a479b
61 changed files with 4306 additions and 654 deletions
+4 -1
View File
@@ -2,6 +2,8 @@
namespace Database\Factories;
use App\Models\Client;
use App\Models\Person\Person;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
@@ -17,7 +19,8 @@ class ClientCaseFactory extends Factory
public function definition(): array
{
return [
//
'client_id' => Client::factory(),
'person_id' => Person::factory(),
];
}
}
+3 -1
View File
@@ -2,6 +2,7 @@
namespace Database\Factories;
use App\Models\Person\Person;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
@@ -17,7 +18,8 @@ class ClientFactory extends Factory
public function definition(): array
{
return [
//
'person_id' => Person::factory(),
'active' => 1,
];
}
}
+8 -1
View File
@@ -2,6 +2,8 @@
namespace Database\Factories;
use App\Models\ClientCase;
use App\Models\ContractType;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
@@ -17,7 +19,12 @@ class ContractFactory extends Factory
public function definition(): array
{
return [
//
'reference' => $this->faker->optional()->bothify('REF-####'),
'start_date' => $this->faker->date(),
'end_date' => $this->faker->optional()->date(),
'client_case_id' => ClientCase::factory(),
'type_id' => ContractType::factory(),
'description' => $this->faker->optional()->sentence(),
];
}
}
@@ -0,0 +1,19 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ContractType>
*/
class ContractTypeFactory extends Factory
{
public function definition(): array
{
return [
'name' => $this->faker->unique()->word(),
'description' => $this->faker->optional()->sentence(),
];
}
}
+2 -1
View File
@@ -17,7 +17,8 @@ class DecisionFactory extends Factory
public function definition(): array
{
return [
//
'name' => $this->faker->unique()->words(2, true),
'color_tag' => $this->faker->optional()->safeColorName(),
];
}
}
+6 -3
View File
@@ -2,6 +2,8 @@
namespace Database\Factories\Person;
use App\Models\Person\PersonGroup;
use App\Models\Person\PersonType;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
@@ -19,13 +21,14 @@ public function definition(): array
return [
'first_name' => $this->faker->firstName(),
'last_name' => $this->faker->lastName(),
'full_name' => fn(array $attrs) => trim(($attrs['first_name'] ?? '').' '.($attrs['last_name'] ?? '')),
'gender' => $this->faker->randomElement(['m','w']),
'full_name' => fn (array $attrs) => trim(($attrs['first_name'] ?? '').' '.($attrs['last_name'] ?? '')),
'gender' => $this->faker->randomElement(['m', 'w']),
'birthday' => $this->faker->optional()->date(),
'tax_number' => $this->faker->optional()->bothify('########'),
'social_security_number' => $this->faker->optional()->bothify('#########'),
'description' => $this->faker->optional()->sentence(),
// group_id/type_id are required; keep null here and let tests/seeds assign or rely on defaults in code paths that use factories
'group_id' => PersonGroup::factory(),
'type_id' => PersonType::factory(),
];
}
}
@@ -9,15 +9,12 @@
*/
class PersonGroupFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
'name' => $this->faker->unique()->word(),
'description' => $this->faker->optional()->sentence(),
'color_tag' => $this->faker->optional()->safeColorName(),
];
}
}
@@ -17,7 +17,8 @@ class PersonTypeFactory extends Factory
public function definition(): array
{
return [
//
'name' => $this->faker->unique()->word(),
'description' => $this->faker->optional()->sentence(),
];
}
}
+3 -1
View File
@@ -17,7 +17,9 @@ class SegmentFactory extends Factory
public function definition(): array
{
return [
//
'name' => $this->faker->unique()->words(2, true),
'description' => $this->faker->sentence(),
'active' => true,
];
}
}
@@ -1,19 +1,76 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
return new class extends Migration
{
public function up(): void
{
// PostgreSQL: drop NOT NULL constraint on description
DB::statement('ALTER TABLE segments ALTER COLUMN description DROP NOT NULL');
$driver = DB::connection()->getDriverName();
if ($driver === 'pgsql') {
// PostgreSQL: drop NOT NULL constraint on description
DB::statement('ALTER TABLE segments ALTER COLUMN description DROP NOT NULL');
return;
}
if ($driver === 'mysql') {
// MySQL / MariaDB
DB::statement('ALTER TABLE segments MODIFY description VARCHAR(255) NULL');
return;
}
// SQLite or other drivers: avoid brittle raw SQL. If Doctrine DBAL isn't installed,
// changing a column may not be supported. Since this is only relaxing NOT NULL,
// we can safely no-op for SQLite tests.
if ($driver === 'sqlite') {
return; // no-op for tests
}
// Fallback attempt using Schema (requires doctrine/dbal; if unavailable, it will be ignored in tests)
Schema::table('segments', function (Blueprint $table): void {
try {
$table->string('description', 255)->nullable()->change();
} catch (\Throwable $e) {
// ignore if not supported in current driver
}
});
}
public function down(): void
{
$driver = DB::connection()->getDriverName();
// Ensure no NULLs before setting NOT NULL
DB::statement("UPDATE segments SET description = '' WHERE description IS NULL");
DB::statement('ALTER TABLE segments ALTER COLUMN description SET NOT NULL');
if ($driver === 'pgsql') {
DB::statement('ALTER TABLE segments ALTER COLUMN description SET NOT NULL');
return;
}
if ($driver === 'mysql') {
DB::statement('ALTER TABLE segments MODIFY description VARCHAR(255) NOT NULL');
return;
}
if ($driver === 'sqlite') {
return; // no-op for tests
}
Schema::table('segments', function (Blueprint $table): void {
try {
$table->string('description', 255)->nullable(false)->change();
} catch (\Throwable $e) {
// ignore
}
});
}
};
@@ -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
{
public function up(): void
{
Schema::table('field_job_settings', function (Blueprint $table) {
$table->foreignId('cancel_decision_id')
->nullable()
->after('complete_decision_id')
->constrained('decisions')
->nullOnDelete();
});
}
public function down(): void
{
Schema::table('field_job_settings', function (Blueprint $table) {
$table->dropForeign(['cancel_decision_id']);
$table->dropColumn('cancel_decision_id');
});
}
};
@@ -0,0 +1,26 @@
<?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('field_job_settings', function (Blueprint $table): void {
$table->foreignId('return_segment_id')
->nullable()
->constrained('segments')
->nullOnDelete()
->after('cancel_decision_id');
});
}
public function down(): void
{
Schema::table('field_job_settings', function (Blueprint $table): void {
$table->dropConstrainedForeignId('return_segment_id');
});
}
};
@@ -0,0 +1,20 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
// Rename columns with typos: asign -> assign, asigned -> assigned
DB::statement('ALTER TABLE field_job_settings RENAME COLUMN asign_decision_id TO assign_decision_id');
DB::statement('ALTER TABLE field_jobs RENAME COLUMN asigned_user_id TO assigned_user_id');
}
public function down(): void
{
DB::statement('ALTER TABLE field_job_settings RENAME COLUMN assign_decision_id TO asign_decision_id');
DB::statement('ALTER TABLE field_jobs RENAME COLUMN assigned_user_id TO asigned_user_id');
}
};
@@ -0,0 +1,26 @@
<?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('field_job_settings', function (Blueprint $table) {
if (! Schema::hasColumn('field_job_settings', 'queue_segment_id')) {
$table->foreignId('queue_segment_id')->nullable()->constrained('segments')->nullOnDelete();
}
});
}
public function down(): void
{
Schema::table('field_job_settings', function (Blueprint $table) {
if (Schema::hasColumn('field_job_settings', 'queue_segment_id')) {
$table->dropConstrainedForeignId('queue_segment_id');
}
});
}
};
+11 -7
View File
@@ -3,10 +3,9 @@
namespace Database\Seeders;
use App\Models\User;
use App\Models\Person\PersonType;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class DatabaseSeeder extends Seeder
{
@@ -17,11 +16,15 @@ public function run(): void
{
// User::factory(10)->create();
User::factory()->create([
'name' => 'Test User',
'email' => 'test@example.com',
'password' => Hash::make("password")
]);
// Ensure a default test user exists (idempotent)
\App\Models\User::query()->updateOrCreate(
['email' => 'test@example.com'],
[
'name' => 'Test User',
'password' => Hash::make('password'),
'email_verified_at' => now(),
]
);
$this->call([
PersonSeeder::class,
@@ -29,6 +32,7 @@ public function run(): void
ActionSeeder::class,
EventSeeder::class,
ImportTemplateSeeder::class,
TestUserSeeder::class,
]);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class TestUserSeeder extends Seeder
{
public function run(): void
{
$email = 'field.tester@example.com';
$password = 'password123';
$name = 'Field Tester';
// Create or update a predictable test user you can use to log in.
$user = User::query()->firstOrCreate(
['email' => $email],
[
'name' => $name,
// Will be auto-hashed by the User model cast.
'password' => $password,
]
);
if (! $user->wasRecentlyCreated) {
$user->name = $name;
$user->password = $password; // auto-hashed by cast
}
if ($user->email_verified_at === null) {
$user->email_verified_at = now();
}
$user->save();
}
}