diff --git a/app/Livewire/Datatable/UsersTable.php b/app/Livewire/Datatable/UsersTable.php
index e20eb97..93f9720 100644
--- a/app/Livewire/Datatable/UsersTable.php
+++ b/app/Livewire/Datatable/UsersTable.php
@@ -65,10 +65,8 @@ public function columns(): array
))
->html(),
- Column::make('Kode Referral', 'referral_code')
- ->format(fn ($value) => Blade::render(
- ''.$value.''
- ))
+ Column::make('Kode Referral', 'referralCode.code')
+ ->format(fn ($value) => Blade::render(''.$value.''))
->html(),
Column::make('Gaji Pokok', 'employee.base_salary')
@@ -139,7 +137,7 @@ public function columns(): array
public function builder(): Builder
{
- return User::select('users.id', 'email', 'username', 'users.status', 'employee.code', 'employee.full_name', 'employee.phone_number', 'employee.base_salary', 'employee.address', 'employee.hire_date', 'employee.resign_date', 'employee.birthdate', 'employee.gender')->with('employee');
+ return User::select('users.id', 'email', 'username', 'users.status', 'employee.code', 'employee.full_name', 'employee.phone_number', 'employee.base_salary', 'employee.address', 'employee.hire_date', 'employee.resign_date', 'employee.birthdate', 'employee.gender')->with(['employee', 'referralCode']);
}
public function filters(): array
diff --git a/app/Models/ReferralCode.php b/app/Models/ReferralCode.php
new file mode 100644
index 0000000..c4b9eca
--- /dev/null
+++ b/app/Models/ReferralCode.php
@@ -0,0 +1,33 @@
+ 'int',
+ ];
+ }
+
+ public function user(): BelongsTo
+ {
+ return $this->belongsTo(User::class);
+ }
+
+ public function referralUsage(): HasOne
+ {
+ return $this->hasOne(ReferralUsage::class);
+ }
+}
diff --git a/app/Models/ReferralUsage.php b/app/Models/ReferralUsage.php
new file mode 100644
index 0000000..b442d63
--- /dev/null
+++ b/app/Models/ReferralUsage.php
@@ -0,0 +1,24 @@
+belongsTo(User::class);
+ }
+
+ public function referralCode(): BelongsTo
+ {
+ return $this->belongsTo(ReferralCode::class);
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index ad040a9..4e829ed 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -41,4 +41,14 @@ public function membership(): HasOne
{
return $this->hasOne(Membership::class);
}
+
+ public function referralCode(): HasOne
+ {
+ return $this->hasOne(ReferralCode::class);
+ }
+
+ public function referralUsage(): HasOne
+ {
+ return $this->hasOne(ReferralUsage::class);
+ }
}
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index 74adc56..6ee2e98 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -3,7 +3,6 @@
namespace Database\Factories;
use App\Enums\UserStatus;
-use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
@@ -11,13 +10,10 @@ class UserFactory extends Factory
{
public function definition(): array
{
- $username = $this->faker->unique()->regexify('[A-Za-z0-9]{8}');
-
return [
'email' => $this->faker->unique()->safeEmail(),
- 'username' => $username,
+ 'username' => fake()->unique()->regexify('[A-Za-z0-9]{8}'),
'password' => Hash::make(config('myconfig.password_default')),
- 'referral_code' => generateReferralCode($username, User::max('id') + 1),
'status' => $this->faker->randomElement(UserStatus::cases()),
];
}
diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php
index 0788000..4ef026a 100644
--- a/database/migrations/0001_01_01_000000_create_users_table.php
+++ b/database/migrations/0001_01_01_000000_create_users_table.php
@@ -17,7 +17,6 @@ public function up(): void
$table->string('email', 100)->unique();
$table->string('username', 20)->unique();
$table->string('password', 97);
- $table->string('referral_code', 20)->unique();
$table->enum('status', [UserStatus::values()])->default(UserStatus::ACTIVE)->comment(UserStatus::comment());
$table->timestamp('last_login_at')->nullable();
$table->timestamp('last_password_change_at')->nullable();
diff --git a/database/migrations/2025_10_01_083444_create_referral_codes_table.php b/database/migrations/2025_10_01_083444_create_referral_codes_table.php
new file mode 100644
index 0000000..6ce5609
--- /dev/null
+++ b/database/migrations/2025_10_01_083444_create_referral_codes_table.php
@@ -0,0 +1,31 @@
+id();
+ $table->foreignId('user_id')->constrained()->cascadeOnDelete();
+ $table->string('code', 20)->unique();
+ $table->unsignedInteger('uses_count')->default(0);
+ $table->timestamps();
+ $table->softDeletes();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('referral_codes');
+ }
+};
diff --git a/database/migrations/2025_10_01_083554_create_referral_usages_table.php b/database/migrations/2025_10_01_083554_create_referral_usages_table.php
new file mode 100644
index 0000000..e251b2d
--- /dev/null
+++ b/database/migrations/2025_10_01_083554_create_referral_usages_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->foreignId('user_id')->constrained()->cascadeOnDelete();
+ $table->foreignId('referral_code_id')->constrained()->cascadeOnDelete();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('referral_usages');
+ }
+};
diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php
index 6ec60c3..44ee5de 100644
--- a/database/seeders/UserSeeder.php
+++ b/database/seeders/UserSeeder.php
@@ -5,6 +5,7 @@
use App\Enums\EmploymentStatus;
use App\Enums\Gender;
use App\Models\Employee;
+use App\Models\ReferralCode;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
@@ -17,7 +18,6 @@ public function run(): void
'email' => 'project.pangestuyoga@gmail.com',
'username' => 'pangestu',
'password' => Hash::make(config('myconfig.password_default')),
- 'referral_code' => generateReferralCode('pangestu', 1),
]);
Employee::create([
@@ -31,5 +31,10 @@ public function run(): void
'hire_date' => now(),
'status' => EmploymentStatus::PERMANENT,
]);
+
+ ReferralCode::create([
+ 'user_id' => $user->id,
+ 'code' => generateReferralCode('pangestu', 1),
+ ]);
}
}
diff --git a/tests/Feature/Livewire/Studio/Master/User/CreateTest.php b/tests/Feature/Livewire/Studio/Master/User/CreateTest.php
index 204d847..e76dcdc 100644
--- a/tests/Feature/Livewire/Studio/Master/User/CreateTest.php
+++ b/tests/Feature/Livewire/Studio/Master/User/CreateTest.php
@@ -26,7 +26,6 @@
->set('form.full_name', $data['full_name'])
->set('form.username', $data['username'])
->set('form.email', $data['email'])
- ->set('form.referral_code', $data['referral_code'])
->set('form.phone_number', $data['phone_number'])
->set('form.base_salary', $data['base_salary'])
->set('form.birthdate', $data['birthdate'])
diff --git a/tests/Feature/Livewire/Studio/Master/User/EditTest.php b/tests/Feature/Livewire/Studio/Master/User/EditTest.php
index c1ff764..f85d93f 100644
--- a/tests/Feature/Livewire/Studio/Master/User/EditTest.php
+++ b/tests/Feature/Livewire/Studio/Master/User/EditTest.php
@@ -33,7 +33,6 @@
->set('form.full_name', $data['full_name'])
->set('form.username', $data['username'])
->set('form.email', $data['email'])
- ->set('form.referral_code', $data['referral_code'])
->set('form.phone_number', $data['phone_number'])
->set('form.base_salary', $data['base_salary'])
->set('form.birthdate', $data['birthdate'])