Add employee, user, and user profile models with enums for status and gender
This commit is contained in:
parent
632296c453
commit
ff1ec1ef66
10
app/Enums/EmployeeStatus.php
Normal file
10
app/Enums/EmployeeStatus.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum EmployeeStatus: string
|
||||||
|
{
|
||||||
|
case ACTIVE = 'active';
|
||||||
|
case INACTIVE = 'inactive';
|
||||||
|
case RESIGNED = 'resigned';
|
||||||
|
}
|
||||||
11
app/Enums/EmploymentStatus.php
Normal file
11
app/Enums/EmploymentStatus.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum EmploymentStatus: string
|
||||||
|
{
|
||||||
|
case FULL_TIME = 'full_time';
|
||||||
|
case PART_TIME = 'part_time';
|
||||||
|
case CONTRACT = 'contract';
|
||||||
|
case TEMPORARY = 'temporary';
|
||||||
|
}
|
||||||
9
app/Enums/Gender.php
Normal file
9
app/Enums/Gender.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum Gender: string
|
||||||
|
{
|
||||||
|
case MALE = 'male';
|
||||||
|
case FEMALE = 'female';
|
||||||
|
}
|
||||||
85
app/Models/Employee.php
Normal file
85
app/Models/Employee.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\EmployeeStatus;
|
||||||
|
use App\Enums\EmploymentStatus;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
#[Guarded(['id'])]
|
||||||
|
#[Appends(['base_salary_formatted'])]
|
||||||
|
class Employee extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'join_date' => 'date',
|
||||||
|
'resign_date' => 'date',
|
||||||
|
'employment_status' => EmploymentStatus::class,
|
||||||
|
'employee_status' => EmployeeStatus::class,
|
||||||
|
'base_salary' => 'integer',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function active(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmployeeStatus::ACTIVE->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function inactive(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmployeeStatus::INACTIVE->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function resigned(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmployeeStatus::RESIGNED->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fullTime(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employment_status', EmploymentStatus::FULL_TIME->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function partTime(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmploymentStatus::PART_TIME->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function contract(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmploymentStatus::CONTRACT->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
public function temporary(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->where('employee_status', EmploymentStatus::TEMPORARY->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function baseSalaryFormatted(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: fn (int $value) => number_format($value, 0, ',', '.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function profile(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(UserProfile::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,31 +2,31 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
use Database\Factories\UserFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
#[Fillable(['name', 'email', 'password'])]
|
#[Guarded(['id'])]
|
||||||
#[Hidden(['password', 'remember_token'])]
|
#[Hidden(['password', 'remember_token'])]
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<UserFactory> */
|
use HasFactory, Notifiable, SoftDeletes;
|
||||||
use HasFactory, Notifiable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the attributes that should be cast.
|
|
||||||
*
|
|
||||||
* @return array<string, string>
|
|
||||||
*/
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email_verified_at' => 'datetime',
|
'is_active' => 'boolean',
|
||||||
|
'last_login_at' => 'datetime',
|
||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function profile(): HasOne
|
||||||
|
{
|
||||||
|
return $this->hasOne(UserProfile::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
app/Models/UserProfile.php
Normal file
34
app/Models/UserProfile.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\Gender;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
#[Guarded(['id'])]
|
||||||
|
class UserProfile extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'gender' => Gender::class,
|
||||||
|
'birth_date' => 'date',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function employee(): HasOne
|
||||||
|
{
|
||||||
|
return $this->hasOne(Employee::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -114,4 +114,5 @@
|
|||||||
|
|
||||||
'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),
|
'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),
|
||||||
|
|
||||||
|
'password_default' => env('PASSWORD_DEFAULT', 'Minimal8@'),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -12,13 +12,17 @@
|
|||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('users', function (Blueprint $table) {
|
Schema::create('users', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->unsignedBigInteger('id', true);
|
||||||
$table->string('name');
|
|
||||||
$table->string('email')->unique();
|
$table->string('email', 100)->unique();
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
$table->string('username', 20)->unique();
|
||||||
$table->string('password');
|
$table->string('password', 255);
|
||||||
$table->rememberToken();
|
$table->boolean('is_active')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamp('last_login_at')->nullable();
|
||||||
|
|
||||||
|
$table->timestamp('created_at')->useCurrent();
|
||||||
|
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
|
|
||||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\Gender;
|
||||||
|
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::create('user_profiles', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete()->unique();
|
||||||
|
|
||||||
|
$table->string('full_name', 200);
|
||||||
|
$table->string('phone_number', 20)->nullable();
|
||||||
|
$table->enum('gender', array_column(Gender::cases(), 'value'))->nullable();
|
||||||
|
$table->date('birth_date')->nullable();
|
||||||
|
$table->text('address')->nullable();
|
||||||
|
|
||||||
|
$table->timestamp('created_at')->useCurrent();
|
||||||
|
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('user_profiles');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\EmployeeStatus;
|
||||||
|
use App\Enums\EmploymentStatus;
|
||||||
|
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::create('employees', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete()->unique();
|
||||||
|
|
||||||
|
$table->string('employee_code', 20)->unique();
|
||||||
|
$table->date('join_date');
|
||||||
|
$table->date('resign_date')->nullable();
|
||||||
|
$table->enum('employment_status', array_column(EmploymentStatus::cases(), 'value'))->default(EmploymentStatus::FULL_TIME->value);
|
||||||
|
$table->enum('employee_status', array_column(EmployeeStatus::cases(), 'value'))->default(EmployeeStatus::ACTIVE->value);
|
||||||
|
$table->unsignedInteger('base_salary');
|
||||||
|
|
||||||
|
$table->timestamp('created_at')->useCurrent();
|
||||||
|
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('employees');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
@ -15,11 +14,8 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// User::factory(10)->create();
|
$this->call([
|
||||||
|
UserSeeder::class,
|
||||||
User::factory()->create([
|
|
||||||
'name' => 'Test User',
|
|
||||||
'email' => 'test@example.com',
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
database/seeders/UserSeeder.php
Normal file
32
database/seeders/UserSeeder.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Enums\Gender;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\UserProfile;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
|
class UserSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
DB::transaction(function () {
|
||||||
|
|
||||||
|
$developer = User::create([
|
||||||
|
'email' => 'project.pangestuyoga@gmail.com',
|
||||||
|
'username' => 'pangestu',
|
||||||
|
'password' => Hash::make(config('auth.password_default')),
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserProfile::create([
|
||||||
|
'user_id' => $developer->id,
|
||||||
|
'full_name' => 'Yoga Pangestu',
|
||||||
|
'phone_number' => '082121495806',
|
||||||
|
'gender' => Gender::MALE->value,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,4 +4,4 @@
|
|||||||
$response = $this->get(route('home'));
|
$response = $this->get(route('home'));
|
||||||
|
|
||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
test('that true is true', function () {
|
test('that true is true', function () {
|
||||||
expect(true)->toBeTrue();
|
expect(true)->toBeTrue();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user