first
This commit is contained in:
1
src/database/.gitignore
vendored
Normal file
1
src/database/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.sqlite*
|
||||
45
src/database/factories/UserFactory.php
Normal file
45
src/database/factories/UserFactory.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends Factory<User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
protected static ?string $password;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the model's email address should be unverified.
|
||||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?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::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->unsignedBigInteger('role_id')->nullable()->index();
|
||||
$table->unsignedBigInteger('department_id')->nullable()->index();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamp('last_login_at')->nullable();
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('sessions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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::create('cache', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->mediumText('value');
|
||||
$table->bigInteger('expiration')->index();
|
||||
});
|
||||
|
||||
Schema::create('cache_locks', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->string('owner');
|
||||
$table->bigInteger('expiration')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('cache');
|
||||
Schema::dropIfExists('cache_locks');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
<?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::create('jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedSmallInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->string('connection');
|
||||
$table->string('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
|
||||
$table->index(['connection', 'queue', 'failed_at']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
Schema::dropIfExists('job_batches');
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,263 @@
|
||||
<?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::create('roles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->string('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('role_permissions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('role_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('module');
|
||||
$table->json('permissions');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('departments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('code')->nullable()->unique();
|
||||
$table->string('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('user_profiles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->unique()->constrained()->cascadeOnDelete();
|
||||
$table->string('public_name')->nullable();
|
||||
$table->string('identification_type')->nullable();
|
||||
$table->string('identification_number')->nullable();
|
||||
$table->string('country_code')->default('+60');
|
||||
$table->string('mobile_no')->nullable();
|
||||
$table->string('correspondence_address')->nullable();
|
||||
$table->string('workplace_address')->nullable();
|
||||
$table->string('occupation')->nullable();
|
||||
$table->decimal('monthly_income', 12, 2)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('import_batches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('filename');
|
||||
$table->string('stored_path')->nullable();
|
||||
$table->foreignId('uploaded_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->unsignedInteger('total_processed')->default(0);
|
||||
$table->unsignedInteger('total_new')->default(0);
|
||||
$table->unsignedInteger('total_updated')->default(0);
|
||||
$table->unsignedInteger('total_missing')->default(0);
|
||||
$table->unsignedInteger('total_failed')->default(0);
|
||||
$table->json('summary')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('property_accounts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('no_akaun')->unique();
|
||||
$table->string('no_akaun_tunggakan')->unique();
|
||||
$table->string('pemilik');
|
||||
$table->string('warganegara')->nullable();
|
||||
$table->string('pelanggan')->nullable();
|
||||
$table->string('status')->nullable();
|
||||
$table->string('bandar')->nullable();
|
||||
$table->string('taman')->nullable();
|
||||
$table->string('rupacara')->nullable();
|
||||
$table->string('kadar')->nullable();
|
||||
$table->string('aktif')->nullable();
|
||||
$table->decimal('tunggakan', 12, 2)->default(0);
|
||||
$table->string('jenis_lot')->nullable();
|
||||
$table->string('no_lot')->nullable();
|
||||
$table->string('jenis_dhm')->nullable();
|
||||
$table->string('no_dhm')->nullable();
|
||||
$table->string('no_syarikat')->nullable();
|
||||
$table->string('alamat_harta')->nullable();
|
||||
$table->string('category')->nullable();
|
||||
$table->string('status_data')->default('Aktif');
|
||||
$table->timestamp('last_imported_at')->nullable();
|
||||
$table->foreignId('import_batch_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('installment_applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('property_account_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->foreignId('assigned_staff_id')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->string('application_no')->unique();
|
||||
$table->string('no_akaun');
|
||||
$table->string('no_akaun_tunggakan');
|
||||
$table->string('category');
|
||||
$table->unsignedTinyInteger('installment_months');
|
||||
$table->decimal('total_arrears', 12, 2)->default(0);
|
||||
$table->string('status')->default('diproses');
|
||||
$table->string('schedule_status')->default('draf');
|
||||
$table->decimal('schedule_total', 12, 2)->default(0);
|
||||
$table->text('staff_remarks')->nullable();
|
||||
$table->foreignId('reviewed_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('reviewed_at')->nullable();
|
||||
$table->timestamp('approved_at')->nullable();
|
||||
$table->timestamp('rejected_at')->nullable();
|
||||
$table->text('rejection_reason')->nullable();
|
||||
$table->string('identification_type')->nullable();
|
||||
$table->string('identification_number')->nullable();
|
||||
$table->string('no_syarikat')->nullable();
|
||||
$table->string('alamat_harta')->nullable();
|
||||
$table->string('alamat_surat_menyurat')->nullable();
|
||||
$table->string('country_code')->default('+60');
|
||||
$table->string('mobile_no')->nullable();
|
||||
$table->string('email')->nullable();
|
||||
$table->string('alamat_tempat_bekerja')->nullable();
|
||||
$table->string('pekerjaan')->nullable();
|
||||
$table->decimal('pendapatan_sebulan', 12, 2)->nullable();
|
||||
$table->string('declaration_name');
|
||||
$table->string('declaration_identification_type');
|
||||
$table->string('declaration_identification_number');
|
||||
$table->date('declaration_date');
|
||||
$table->boolean('declaration_accepted')->default(false);
|
||||
$table->string('ic_attachment_path')->nullable();
|
||||
$table->timestamp('printed_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('installment_schedules', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('installment_application_id')->constrained()->cascadeOnDelete();
|
||||
$table->unsignedTinyInteger('installment_no');
|
||||
$table->date('due_date')->nullable();
|
||||
$table->decimal('amount', 12, 2)->default(0);
|
||||
$table->string('payment_status')->default('belum_bayar');
|
||||
$table->timestamp('paid_at')->nullable();
|
||||
$table->text('notes')->nullable();
|
||||
$table->boolean('is_confirmed')->default(false);
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('payments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('installment_application_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('installment_schedule_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('transaction_no')->unique();
|
||||
$table->string('receipt_no')->nullable();
|
||||
$table->string('biller_code')->default('37317');
|
||||
$table->string('ref_1');
|
||||
$table->string('ref_2');
|
||||
$table->decimal('amount', 12, 2);
|
||||
$table->string('status')->default('pending');
|
||||
$table->json('payload')->nullable();
|
||||
$table->timestamp('paid_at')->nullable();
|
||||
$table->text('remarks')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('notifications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('type')->default('system');
|
||||
$table->string('title');
|
||||
$table->text('message');
|
||||
$table->string('action_url')->nullable();
|
||||
$table->boolean('is_read')->default(false);
|
||||
$table->timestamp('read_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('email_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->foreignId('installment_application_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('recipient_email');
|
||||
$table->string('subject');
|
||||
$table->text('body')->nullable();
|
||||
$table->string('status')->default('queued');
|
||||
$table->timestamp('sent_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('tasks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('installment_application_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->foreignId('assigned_to')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->foreignId('assigned_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->string('title');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('priority')->default('normal');
|
||||
$table->string('status')->default('belum_selesai');
|
||||
$table->timestamp('due_at')->nullable();
|
||||
$table->timestamp('completed_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('application_histories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('installment_application_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('action');
|
||||
$table->string('old_status')->nullable();
|
||||
$table->string('new_status')->nullable();
|
||||
$table->text('remarks')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('system_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('group')->default('general');
|
||||
$table->string('key')->unique();
|
||||
$table->string('label');
|
||||
$table->text('value')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('audit_trails', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->foreignId('installment_application_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('action');
|
||||
$table->string('module');
|
||||
$table->text('description');
|
||||
$table->json('old_values')->nullable();
|
||||
$table->json('new_values')->nullable();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('audit_trails');
|
||||
Schema::dropIfExists('system_settings');
|
||||
Schema::dropIfExists('application_histories');
|
||||
Schema::dropIfExists('tasks');
|
||||
Schema::dropIfExists('email_logs');
|
||||
Schema::dropIfExists('notifications');
|
||||
Schema::dropIfExists('payments');
|
||||
Schema::dropIfExists('installment_schedules');
|
||||
Schema::dropIfExists('installment_applications');
|
||||
Schema::dropIfExists('property_accounts');
|
||||
Schema::dropIfExists('import_batches');
|
||||
Schema::dropIfExists('user_profiles');
|
||||
Schema::dropIfExists('departments');
|
||||
Schema::dropIfExists('role_permissions');
|
||||
Schema::dropIfExists('roles');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
<?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('installment_applications', function (Blueprint $table) {
|
||||
$table->string('jenis_lot')->nullable()->after('no_syarikat');
|
||||
$table->string('no_lot')->nullable()->after('jenis_lot');
|
||||
$table->string('jenis_dhm')->nullable()->after('no_lot');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('installment_applications', function (Blueprint $table) {
|
||||
$table->dropColumn(['jenis_lot', 'no_lot', 'jenis_dhm']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
<?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('property_accounts', function (Blueprint $table) {
|
||||
$table->string('no_bgnn')->nullable()->after('no_akaun_tunggakan');
|
||||
$table->string('nama_jalan')->nullable()->after('no_bgnn');
|
||||
$table->decimal('cukai_harta', 12, 2)->default(0)->after('kadar');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('property_accounts', function (Blueprint $table) {
|
||||
$table->dropColumn(['no_bgnn', 'nama_jalan', 'cukai_harta']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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('import_batches', function (Blueprint $table) {
|
||||
$table->string('import_type')->default('arrears')->after('stored_path');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('import_batches', function (Blueprint $table) {
|
||||
$table->dropColumn('import_type');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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('installment_applications', function (Blueprint $table): void {
|
||||
$table->string('no_dhm')->nullable()->after('no_lot');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('installment_applications', function (Blueprint $table): void {
|
||||
$table->dropColumn('no_dhm');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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('installment_applications', function (Blueprint $table): void {
|
||||
$table->decimal('property_tax_half_amount', 12, 2)->nullable()->after('total_arrears');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('installment_applications', function (Blueprint $table): void {
|
||||
$table->dropColumn('property_tax_half_amount');
|
||||
});
|
||||
}
|
||||
};
|
||||
529
src/database/seeders/DatabaseSeeder.php
Normal file
529
src/database/seeders/DatabaseSeeder.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\ApplicationStatus;
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\ApplicationHistory;
|
||||
use App\Models\AuditTrail;
|
||||
use App\Models\Department;
|
||||
use App\Models\EmailLog;
|
||||
use App\Models\ImportBatch;
|
||||
use App\Models\InstallmentApplication;
|
||||
use App\Models\InstallmentSchedule;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PropertyAccount;
|
||||
use App\Models\Role;
|
||||
use App\Models\RolePermission;
|
||||
use App\Models\SystemNotification;
|
||||
use App\Models\SystemSetting;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Models\UserProfile;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$roles = collect([
|
||||
UserRole::ADMIN->value => Role::create([
|
||||
'name' => 'Admin',
|
||||
'slug' => UserRole::ADMIN->value,
|
||||
'description' => 'Akses penuh pemantauan, laporan dan tetapan sistem.',
|
||||
]),
|
||||
UserRole::STAFF->value => Role::create([
|
||||
'name' => 'Staff',
|
||||
'slug' => UserRole::STAFF->value,
|
||||
'description' => 'Semak permohonan, input jadual manual dan cetak borang.',
|
||||
]),
|
||||
UserRole::PUBLIC->value => Role::create([
|
||||
'name' => 'Pengguna Awam',
|
||||
'slug' => UserRole::PUBLIC->value,
|
||||
'description' => 'Mohon ansuran, lihat jadual manual dan buat bayaran dummy.',
|
||||
]),
|
||||
]);
|
||||
|
||||
foreach ([
|
||||
UserRole::ADMIN->value => [
|
||||
'Dashboard' => ['view'],
|
||||
'Pengurusan Pengguna' => ['view', 'create', 'edit', 'reset_password'],
|
||||
'Laporan' => ['view', 'export'],
|
||||
'Audit Trail' => ['view'],
|
||||
],
|
||||
UserRole::STAFF->value => [
|
||||
'Dashboard Staff' => ['view'],
|
||||
'Permohonan' => ['view', 'review', 'print'],
|
||||
'Kemaskini Bayaran Pukal' => ['view', 'upload'],
|
||||
'Import Excel' => ['view', 'upload'],
|
||||
],
|
||||
UserRole::PUBLIC->value => [
|
||||
'Dashboard Pengguna Awam' => ['view'],
|
||||
'Permohonan Saya' => ['view', 'create'],
|
||||
'Bayaran Dummy JomPAY' => ['view', 'pay'],
|
||||
],
|
||||
] as $roleSlug => $permissions) {
|
||||
foreach ($permissions as $module => $access) {
|
||||
RolePermission::create([
|
||||
'role_id' => $roles[$roleSlug]->id,
|
||||
'module' => $module,
|
||||
'permissions' => $access,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$department = Department::create([
|
||||
'name' => 'Unit Hasil & Tunggakan',
|
||||
'code' => 'UHT',
|
||||
'description' => 'Bahagian pengurusan tunggakan cukai harta dan ansuran.',
|
||||
]);
|
||||
|
||||
$admin = User::create([
|
||||
'name' => 'Admin MyAnsuran',
|
||||
'email' => 'admin@myansuran.test',
|
||||
'password' => Hash::make('password'),
|
||||
'role_id' => $roles[UserRole::ADMIN->value]->id,
|
||||
'department_id' => $department->id,
|
||||
'last_login_at' => now()->subHours(2),
|
||||
]);
|
||||
|
||||
$staff = User::create([
|
||||
'name' => 'Pegawai Semakan',
|
||||
'email' => 'staff@myansuran.test',
|
||||
'password' => Hash::make('password'),
|
||||
'role_id' => $roles[UserRole::STAFF->value]->id,
|
||||
'department_id' => $department->id,
|
||||
'last_login_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$publicUser = User::create([
|
||||
'name' => 'Nur Balqis',
|
||||
'email' => 'user@myansuran.test',
|
||||
'password' => Hash::make('password'),
|
||||
'role_id' => $roles[UserRole::PUBLIC->value]->id,
|
||||
'last_login_at' => now()->subMinutes(20),
|
||||
]);
|
||||
|
||||
UserProfile::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'public_name' => 'Nur Balqis Binti Rahman',
|
||||
'identification_type' => 'MyKad',
|
||||
'identification_number' => '920101-01-2345',
|
||||
'country_code' => '+60',
|
||||
'mobile_no' => '123456789',
|
||||
'correspondence_address' => 'No. 88, Jalan Setia 3, Taman Setia Indah, Johor Bahru, Johor',
|
||||
'workplace_address' => 'Pejabat Pengurusan BizHub, Iskandar Puteri, Johor',
|
||||
'occupation' => 'Eksekutif Operasi',
|
||||
'monthly_income' => 4200.00,
|
||||
]);
|
||||
|
||||
$this->seedSystemSettings();
|
||||
|
||||
if (! app()->environment('testing')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$importBatch = ImportBatch::create([
|
||||
'filename' => 'property-accounts-demo.xlsx',
|
||||
'stored_path' => 'imports/property-accounts-demo.xlsx',
|
||||
'import_type' => 'arrears',
|
||||
'uploaded_by' => $staff->id,
|
||||
'total_processed' => 10,
|
||||
'total_new' => 10,
|
||||
'total_updated' => 0,
|
||||
'total_missing' => 0,
|
||||
'total_failed' => 0,
|
||||
'summary' => ['seeded' => true],
|
||||
]);
|
||||
|
||||
$propertyAccounts = collect([
|
||||
['A1001', 'NBE1001', 'Nur Balqis Binti Rahman', 'Johor Bahru', 'Taman Setia Indah', 'Banglo', '4.5%', 1200, 'Kediaman'],
|
||||
['A1002', 'NBE1002', 'Syarikat Maju Bina Sdn Bhd', 'Iskandar Puteri', 'Kawasan Perindustrian Gelang Patah', 'Kilang', '6.0%', 4500, 'Industri'],
|
||||
['A1003', 'NBE1003', 'Kedai Seri Jaya Enterprise', 'Johor Bahru', 'Taman Molek', 'Kedai Pejabat', '5.5%', 7800, 'Perdagangan'],
|
||||
['A1004', 'NBE1004', 'Puan Salmah Binti Jusoh', 'Skudai', 'Taman Universiti', 'Teres', '4.0%', 1600, 'Kediaman'],
|
||||
['A1005', 'NBE1005', 'Warisan Teguh Industries', 'Pasir Gudang', 'Kawasan Industri Tanjung Langsat', 'Gudang', '6.8%', 9800, 'Industri'],
|
||||
['A1006', 'NBE1006', 'Restoran Selera Selatan', 'Johor Bahru', 'Bandar Dato Onn', 'Premis Niaga', '5.2%', 3100, 'Perdagangan'],
|
||||
['A1007', 'NBE1007', 'Encik Azhar Bin Jaafar', 'Kulai', 'Taman Putri', 'Teres', '4.1%', 1400, 'Kediaman'],
|
||||
['A1008', 'NBE1008', 'Mutiara Logistic Sdn Bhd', 'Iskandar Puteri', 'Nusajaya Tech Park', 'Lot Industri', '6.4%', 8600, 'Industri'],
|
||||
['A1009', 'NBE1009', 'Butik Anggun Mawar', 'Johor Bahru', 'Taman Mount Austin', 'Lot Komersial', '5.1%', 2600, 'Perdagangan'],
|
||||
['A1010', 'NBE1010', 'Puan Hajar Binti Osman', 'Skudai', 'Taman Sri Pulai', 'Apartment', '3.9%', 900, 'Kediaman'],
|
||||
])->map(function (array $row) use ($importBatch) {
|
||||
[$noAkaun, $noAkaunTunggakan, $pemilik, $bandar, $taman, $rupacara, $kadar, $tunggakan, $category] = $row;
|
||||
|
||||
return PropertyAccount::create([
|
||||
'no_akaun' => $noAkaun,
|
||||
'no_akaun_tunggakan' => $noAkaunTunggakan,
|
||||
'no_bgnn' => 'BGN-'.str($noAkaun)->after('A'),
|
||||
'nama_jalan' => 'Jalan Demo '.str($noAkaun)->after('A'),
|
||||
'pemilik' => $pemilik,
|
||||
'warganegara' => 'Ya',
|
||||
'pelanggan' => 'Aktif',
|
||||
'status' => 'Tunggakan',
|
||||
'bandar' => $bandar,
|
||||
'taman' => $taman,
|
||||
'rupacara' => $rupacara,
|
||||
'kadar' => $kadar,
|
||||
'cukai_harta' => round($tunggakan * 0.35, 2),
|
||||
'aktif' => 'Ya',
|
||||
'tunggakan' => $tunggakan,
|
||||
'jenis_lot' => 'Komersial / Kediaman',
|
||||
'no_lot' => 'LOT-'.str($noAkaun)->after('A'),
|
||||
'jenis_dhm' => 'Hakmilik Kekal',
|
||||
'no_dhm' => 'DHM-'.str($noAkaun)->after('A'),
|
||||
'no_syarikat' => str($pemilik)->contains('Sdn Bhd') ? '201901234567' : null,
|
||||
'alamat_harta' => $taman.', '.$bandar.', Johor',
|
||||
'category' => $category,
|
||||
'status_data' => 'Aktif',
|
||||
'last_imported_at' => now(),
|
||||
'import_batch_id' => $importBatch->id,
|
||||
]);
|
||||
});
|
||||
|
||||
$activeApplication = InstallmentApplication::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'property_account_id' => $propertyAccounts[0]->id,
|
||||
'assigned_staff_id' => $staff->id,
|
||||
'application_no' => 'MYA-202605-0001',
|
||||
'no_akaun' => $propertyAccounts[0]->no_akaun,
|
||||
'no_akaun_tunggakan' => $propertyAccounts[0]->no_akaun_tunggakan,
|
||||
'category' => 'Kediaman',
|
||||
'installment_months' => 4,
|
||||
'total_arrears' => 1200.00,
|
||||
'status' => ApplicationStatus::ACTIVE->value,
|
||||
'schedule_status' => 'disahkan',
|
||||
'schedule_total' => 1200.00,
|
||||
'staff_remarks' => 'Permohonan lengkap. Bayaran pertama dipandu pada kadar minimum 30%.',
|
||||
'reviewed_by' => $staff->id,
|
||||
'reviewed_at' => now()->subDays(5),
|
||||
'approved_at' => now()->subDays(5),
|
||||
'identification_type' => 'MyKad',
|
||||
'identification_number' => '920101-01-2345',
|
||||
'no_lot' => $propertyAccounts[0]->no_lot,
|
||||
'no_dhm' => $propertyAccounts[0]->no_dhm,
|
||||
'no_syarikat' => $propertyAccounts[0]->no_syarikat,
|
||||
'alamat_harta' => $propertyAccounts[0]->no_bgnn.', '.$propertyAccounts[0]->nama_jalan,
|
||||
'alamat_surat_menyurat' => 'No. 88, Jalan Setia 3, Taman Setia Indah, Johor Bahru, Johor',
|
||||
'country_code' => '+60',
|
||||
'mobile_no' => '123456789',
|
||||
'email' => $publicUser->email,
|
||||
'alamat_tempat_bekerja' => 'Pejabat Pengurusan BizHub, Iskandar Puteri, Johor',
|
||||
'pekerjaan' => 'Eksekutif Operasi',
|
||||
'pendapatan_sebulan' => 4200.00,
|
||||
'declaration_name' => 'Nur Balqis Binti Rahman',
|
||||
'declaration_identification_type' => 'MyKad',
|
||||
'declaration_identification_number' => '920101-01-2345',
|
||||
'declaration_date' => now()->subDays(6)->toDateString(),
|
||||
'declaration_accepted' => true,
|
||||
'printed_at' => now()->subDays(4),
|
||||
'created_at' => now()->subDays(6),
|
||||
'updated_at' => now()->subDays(4),
|
||||
]);
|
||||
|
||||
collect([
|
||||
[1, 360.00, now()->subDays(4)->toDateString(), 'dibayar'],
|
||||
[2, 280.00, now()->addDays(5)->toDateString(), 'belum_bayar'],
|
||||
[3, 280.00, now()->addMonth()->toDateString(), 'belum_bayar'],
|
||||
[4, 280.00, now()->addMonths(2)->toDateString(), 'belum_bayar'],
|
||||
])->each(function (array $schedule) use ($activeApplication, $staff) {
|
||||
InstallmentSchedule::create([
|
||||
'installment_application_id' => $activeApplication->id,
|
||||
'installment_no' => $schedule[0],
|
||||
'amount' => $schedule[1],
|
||||
'due_date' => $schedule[2],
|
||||
'payment_status' => $schedule[3],
|
||||
'paid_at' => $schedule[3] === 'dibayar' ? now()->subDays(3) : null,
|
||||
'is_confirmed' => true,
|
||||
'created_by' => $staff->id,
|
||||
]);
|
||||
});
|
||||
|
||||
$processingApplication = InstallmentApplication::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'property_account_id' => $propertyAccounts[1]->id,
|
||||
'assigned_staff_id' => $staff->id,
|
||||
'application_no' => 'MYA-202605-0002',
|
||||
'no_akaun' => $propertyAccounts[1]->no_akaun,
|
||||
'no_akaun_tunggakan' => $propertyAccounts[1]->no_akaun_tunggakan,
|
||||
'category' => 'Industri',
|
||||
'installment_months' => 3,
|
||||
'total_arrears' => 4500.00,
|
||||
'status' => ApplicationStatus::PROCESSING->value,
|
||||
'schedule_status' => 'draf',
|
||||
'schedule_total' => 0,
|
||||
'identification_type' => 'MyKad',
|
||||
'identification_number' => '920101-01-2345',
|
||||
'no_lot' => $propertyAccounts[1]->no_lot,
|
||||
'no_dhm' => $propertyAccounts[1]->no_dhm,
|
||||
'no_syarikat' => $propertyAccounts[1]->no_syarikat,
|
||||
'alamat_harta' => $propertyAccounts[1]->no_bgnn.', '.$propertyAccounts[1]->nama_jalan,
|
||||
'alamat_surat_menyurat' => 'No. 88, Jalan Setia 3, Taman Setia Indah, Johor Bahru, Johor',
|
||||
'country_code' => '+60',
|
||||
'mobile_no' => '123456789',
|
||||
'email' => $publicUser->email,
|
||||
'alamat_tempat_bekerja' => 'Pejabat Pengurusan BizHub, Iskandar Puteri, Johor',
|
||||
'pekerjaan' => 'Eksekutif Operasi',
|
||||
'pendapatan_sebulan' => 4200.00,
|
||||
'declaration_name' => 'Nur Balqis Binti Rahman',
|
||||
'declaration_identification_type' => 'MyKad',
|
||||
'declaration_identification_number' => '920101-01-2345',
|
||||
'declaration_date' => now()->subDays(2)->toDateString(),
|
||||
'declaration_accepted' => true,
|
||||
'created_at' => now()->subDays(2),
|
||||
'updated_at' => now()->subDays(2),
|
||||
]);
|
||||
|
||||
$failedApplication = InstallmentApplication::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'property_account_id' => $propertyAccounts[2]->id,
|
||||
'assigned_staff_id' => $staff->id,
|
||||
'application_no' => 'MYA-202604-0003',
|
||||
'no_akaun' => $propertyAccounts[2]->no_akaun,
|
||||
'no_akaun_tunggakan' => $propertyAccounts[2]->no_akaun_tunggakan,
|
||||
'category' => 'Perdagangan',
|
||||
'installment_months' => 2,
|
||||
'total_arrears' => 7800.00,
|
||||
'status' => ApplicationStatus::FAILED->value,
|
||||
'schedule_status' => 'draf',
|
||||
'schedule_total' => 5000.00,
|
||||
'staff_remarks' => 'Dokumen sokongan tidak lengkap. Sila kemukakan semula salinan IC yang jelas.',
|
||||
'reviewed_by' => $staff->id,
|
||||
'reviewed_at' => now()->subMonth(),
|
||||
'rejected_at' => now()->subMonth(),
|
||||
'rejection_reason' => 'Dokumen sokongan tidak lengkap.',
|
||||
'identification_type' => 'MyKad',
|
||||
'identification_number' => '920101-01-2345',
|
||||
'no_lot' => $propertyAccounts[2]->no_lot,
|
||||
'no_dhm' => $propertyAccounts[2]->no_dhm,
|
||||
'no_syarikat' => $propertyAccounts[2]->no_syarikat,
|
||||
'alamat_harta' => $propertyAccounts[2]->no_bgnn.', '.$propertyAccounts[2]->nama_jalan,
|
||||
'alamat_surat_menyurat' => 'No. 88, Jalan Setia 3, Taman Setia Indah, Johor Bahru, Johor',
|
||||
'country_code' => '+60',
|
||||
'mobile_no' => '123456789',
|
||||
'email' => $publicUser->email,
|
||||
'alamat_tempat_bekerja' => 'Pejabat Pengurusan BizHub, Iskandar Puteri, Johor',
|
||||
'pekerjaan' => 'Eksekutif Operasi',
|
||||
'pendapatan_sebulan' => 4200.00,
|
||||
'declaration_name' => 'Nur Balqis Binti Rahman',
|
||||
'declaration_identification_type' => 'MyKad',
|
||||
'declaration_identification_number' => '920101-01-2345',
|
||||
'declaration_date' => now()->subMonth()->toDateString(),
|
||||
'declaration_accepted' => true,
|
||||
'printed_at' => now()->subMonth()->addDay(),
|
||||
'created_at' => now()->subMonth()->subDays(2),
|
||||
'updated_at' => now()->subMonth()->addDay(),
|
||||
]);
|
||||
|
||||
$completedApplication = InstallmentApplication::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'property_account_id' => $propertyAccounts[3]->id,
|
||||
'assigned_staff_id' => $staff->id,
|
||||
'application_no' => 'MYA-202603-0004',
|
||||
'no_akaun' => $propertyAccounts[3]->no_akaun,
|
||||
'no_akaun_tunggakan' => $propertyAccounts[3]->no_akaun_tunggakan,
|
||||
'category' => 'Kediaman',
|
||||
'installment_months' => 2,
|
||||
'total_arrears' => 1600.00,
|
||||
'status' => ApplicationStatus::COMPLETED->value,
|
||||
'schedule_status' => 'disahkan',
|
||||
'schedule_total' => 1600.00,
|
||||
'staff_remarks' => 'Semua bayaran telah dijelaskan.',
|
||||
'reviewed_by' => $staff->id,
|
||||
'reviewed_at' => now()->subMonths(2),
|
||||
'approved_at' => now()->subMonths(2),
|
||||
'identification_type' => 'MyKad',
|
||||
'identification_number' => '920101-01-2345',
|
||||
'no_lot' => $propertyAccounts[3]->no_lot,
|
||||
'no_dhm' => $propertyAccounts[3]->no_dhm,
|
||||
'no_syarikat' => $propertyAccounts[3]->no_syarikat,
|
||||
'alamat_harta' => $propertyAccounts[3]->no_bgnn.', '.$propertyAccounts[3]->nama_jalan,
|
||||
'alamat_surat_menyurat' => 'No. 88, Jalan Setia 3, Taman Setia Indah, Johor Bahru, Johor',
|
||||
'country_code' => '+60',
|
||||
'mobile_no' => '123456789',
|
||||
'email' => $publicUser->email,
|
||||
'alamat_tempat_bekerja' => 'Pejabat Pengurusan BizHub, Iskandar Puteri, Johor',
|
||||
'pekerjaan' => 'Eksekutif Operasi',
|
||||
'pendapatan_sebulan' => 4200.00,
|
||||
'declaration_name' => 'Nur Balqis Binti Rahman',
|
||||
'declaration_identification_type' => 'MyKad',
|
||||
'declaration_identification_number' => '920101-01-2345',
|
||||
'declaration_date' => now()->subMonths(2)->toDateString(),
|
||||
'declaration_accepted' => true,
|
||||
'printed_at' => now()->subMonths(2)->addDays(2),
|
||||
'created_at' => now()->subMonths(2)->subDays(3),
|
||||
'updated_at' => now()->subMonth(),
|
||||
]);
|
||||
|
||||
collect([
|
||||
[$completedApplication, 1, 800.00, now()->subMonths(2)->addDays(5)->toDateString()],
|
||||
[$completedApplication, 2, 800.00, now()->subMonth()->toDateString()],
|
||||
])->each(function (array $schedule) use ($staff) {
|
||||
InstallmentSchedule::create([
|
||||
'installment_application_id' => $schedule[0]->id,
|
||||
'installment_no' => $schedule[1],
|
||||
'amount' => $schedule[2],
|
||||
'due_date' => $schedule[3],
|
||||
'payment_status' => 'dibayar',
|
||||
'paid_at' => Carbon::parse($schedule[3])->endOfDay(),
|
||||
'is_confirmed' => true,
|
||||
'created_by' => $staff->id,
|
||||
]);
|
||||
});
|
||||
|
||||
Task::insert([
|
||||
[
|
||||
'installment_application_id' => $processingApplication->id,
|
||||
'assigned_to' => $staff->id,
|
||||
'assigned_by' => $admin->id,
|
||||
'title' => 'Semak permohonan '.$processingApplication->application_no,
|
||||
'description' => 'Permohonan baharu menunggu input amaun ansuran manual.',
|
||||
'priority' => 'tinggi',
|
||||
'status' => 'belum_selesai',
|
||||
'due_at' => now()->addDay(),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'installment_application_id' => $activeApplication->id,
|
||||
'assigned_to' => $staff->id,
|
||||
'assigned_by' => $admin->id,
|
||||
'title' => 'Pantau baki ansuran '.$activeApplication->application_no,
|
||||
'description' => 'Semak kemasukan bayaran ansuran bulan kedua.',
|
||||
'priority' => 'normal',
|
||||
'status' => 'belum_selesai',
|
||||
'due_at' => now()->addWeek(),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
|
||||
$activePaymentSchedule = $activeApplication->schedules()->first();
|
||||
Payment::create([
|
||||
'installment_application_id' => $activeApplication->id,
|
||||
'installment_schedule_id' => $activePaymentSchedule?->id,
|
||||
'user_id' => $publicUser->id,
|
||||
'transaction_no' => 'TRX-DEMO-1001',
|
||||
'receipt_no' => 'RCPT-DEMO-1001',
|
||||
'ref_1' => $activeApplication->no_akaun,
|
||||
'ref_2' => $publicUser->email,
|
||||
'amount' => 360.00,
|
||||
'status' => 'success',
|
||||
'payload' => ['channel' => 'JomPAY Dummy'],
|
||||
'paid_at' => now()->subDays(3),
|
||||
'remarks' => 'Bayaran pertama berjaya.',
|
||||
]);
|
||||
|
||||
foreach ($completedApplication->schedules as $index => $schedule) {
|
||||
Payment::create([
|
||||
'installment_application_id' => $completedApplication->id,
|
||||
'installment_schedule_id' => $schedule->id,
|
||||
'user_id' => $publicUser->id,
|
||||
'transaction_no' => 'TRX-DEMO-200'.($index + 1),
|
||||
'receipt_no' => 'RCPT-DEMO-200'.($index + 1),
|
||||
'ref_1' => $completedApplication->no_akaun,
|
||||
'ref_2' => $publicUser->email,
|
||||
'amount' => $schedule->amount,
|
||||
'status' => 'success',
|
||||
'payload' => ['channel' => 'JomPAY Dummy'],
|
||||
'paid_at' => $schedule->paid_at,
|
||||
'remarks' => 'Bayaran ansuran selesai.',
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
[$activeApplication, $publicUser, 'permohonan_dihantar', null, ApplicationStatus::ACTIVE->value, 'Permohonan diterima dan jadual manual disahkan.'],
|
||||
[$processingApplication, $publicUser, 'permohonan_dihantar', null, ApplicationStatus::PROCESSING->value, 'Permohonan sedang diproses oleh staff.'],
|
||||
[$failedApplication, $staff, 'permohonan_ditolak', ApplicationStatus::PROCESSING->value, ApplicationStatus::FAILED->value, 'Dokumen sokongan tidak lengkap.'],
|
||||
[$completedApplication, $staff, 'akaun_ansuran_selesai', ApplicationStatus::ACTIVE->value, ApplicationStatus::COMPLETED->value, 'Semua ansuran telah dibayar.'],
|
||||
] as $history) {
|
||||
ApplicationHistory::create([
|
||||
'installment_application_id' => $history[0]->id,
|
||||
'user_id' => $history[1]->id,
|
||||
'action' => $history[2],
|
||||
'old_status' => $history[3],
|
||||
'new_status' => $history[4],
|
||||
'remarks' => $history[5],
|
||||
'metadata' => ['seeded' => true],
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
['Permohonan diterima', 'Permohonan MYA-202605-0001 telah disahkan dan jadual bayaran dipaparkan.', $activeApplication],
|
||||
['Permohonan masih diproses', 'Permohonan MYA-202605-0002 sedang disemak oleh staff.', $processingApplication],
|
||||
['Permohonan ditolak', 'Permohonan MYA-202604-0003 ditolak. Sila semak ulasan pegawai.', $failedApplication],
|
||||
] as $notification) {
|
||||
SystemNotification::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'type' => 'application',
|
||||
'title' => $notification[0],
|
||||
'message' => $notification[1],
|
||||
'action_url' => '/portal/applications/'.$notification[2]->id,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
['Permohonan diterima', 'Jadual bayaran manual untuk MYA-202605-0001 telah disahkan.', $activeApplication],
|
||||
['Permohonan ditolak', 'Permohonan MYA-202604-0003 memerlukan semakan semula dokumen.', $failedApplication],
|
||||
] as $email) {
|
||||
EmailLog::create([
|
||||
'user_id' => $publicUser->id,
|
||||
'installment_application_id' => $email[2]->id,
|
||||
'recipient_email' => $publicUser->email,
|
||||
'subject' => $email[0],
|
||||
'body' => $email[1],
|
||||
'status' => 'sent',
|
||||
'sent_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
[$admin, 'login', 'Authentication', 'Admin log masuk ke sistem.'],
|
||||
[$publicUser, 'hantar_permohonan', 'Permohonan Ansuran', 'Pengguna menghantar permohonan baharu.'],
|
||||
[$staff, 'semak_permohonan', 'Semakan Staff', 'Staff mengesahkan jadual ansuran manual.'],
|
||||
[$staff, 'upload_excel', 'Import Excel', 'Staff memuat naik Excel data akaun cukai harta.'],
|
||||
[$publicUser, 'bayaran_dummy', 'Pembayaran', 'Pengguna membuat bayaran dummy melalui JomPAY.'],
|
||||
] as $audit) {
|
||||
AuditTrail::create([
|
||||
'user_id' => $audit[0]->id,
|
||||
'installment_application_id' => $activeApplication->id,
|
||||
'action' => $audit[1],
|
||||
'module' => $audit[2],
|
||||
'description' => $audit[3],
|
||||
'old_values' => ['seeded' => true],
|
||||
'new_values' => ['seeded' => true],
|
||||
'ip_address' => '127.0.0.1',
|
||||
'user_agent' => 'Seeder',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function seedSystemSettings(): void
|
||||
{
|
||||
foreach ([
|
||||
['general', 'max_installment_months', 'Jumlah maksimum ansuran', '6', 'Had maksimum tempoh ansuran yang dibenarkan.'],
|
||||
['general', 'minimum_first_payment_residential', 'Kediaman - Panduan Bayaran Awal', '30', 'Peratus panduan bayaran pertama untuk kediaman.'],
|
||||
['general', 'minimum_first_payment_industrial', 'Industri - Panduan Bayaran Awal', '50', 'Peratus panduan bayaran pertama untuk industri.'],
|
||||
['general', 'minimum_first_payment_commercial', 'Perdagangan - Panduan Bayaran Awal', '50', 'Peratus panduan bayaran pertama untuk perdagangan.'],
|
||||
['department', 'department_name', 'Nama Jabatan', 'Majlis Bandaraya Iskandar Puteri', 'Nama jabatan untuk paparan portal.'],
|
||||
['payment', 'jompay_biller_code', 'Biller Code JomPAY', '37317', 'Kod pengebil untuk demo pembayaran JomPAY.'],
|
||||
] as $setting) {
|
||||
SystemSetting::updateOrCreate(
|
||||
['key' => $setting[1]],
|
||||
[
|
||||
'group' => $setting[0],
|
||||
'label' => $setting[2],
|
||||
'value' => $setting[3],
|
||||
'description' => $setting[4],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user