Files
nnterp-react-admin/database/seeders/DemoPayrollStructureSeeder.php
2026-03-13 20:49:46 +08:00

100 lines
4.1 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Workdo\Payroll\Models\EmployeeSalaryStructure;
use Workdo\Payroll\Models\EmployeeSalaryItem;
use Workdo\Payroll\Models\SalaryComponent;
use Workdo\Payroll\Models\PayGroup;
use Workdo\Hrm\Models\Employee;
class DemoPayrollStructureSeeder extends Seeder
{
public function run(DemoContext $ctx): void
{
if (EmployeeSalaryStructure::where('created_by', $ctx->userId)->exists()) {
return;
}
if (empty($ctx->employeeUserIds)) {
return;
}
$payGroupId = PayGroup::where('created_by', $ctx->userId)->first()?->id;
if (!$payGroupId) return;
$earningComponents = SalaryComponent::where('created_by', $ctx->userId)
->where('type', 'earning')->where('is_active', true)->get();
$deductionComponents = SalaryComponent::where('created_by', $ctx->userId)
->where('type', 'deduction')->where('is_active', true)->get();
$salaryTiers = [
['gross' => 25000, 'daily' => 961.54],
['gross' => 30000, 'daily' => 1153.85],
['gross' => 35000, 'daily' => 1346.15],
['gross' => 40000, 'daily' => 1538.46],
['gross' => 50000, 'daily' => 1923.08],
['gross' => 60000, 'daily' => 2307.69],
['gross' => 75000, 'daily' => 2884.62],
['gross' => 90000, 'daily' => 3461.54],
];
foreach ($ctx->employeeUserIds as $index => $userId) {
$tier = $salaryTiers[$index % count($salaryTiers)];
$structure = EmployeeSalaryStructure::create([
'user_id' => $userId,
'gross_salary' => $tier['gross'],
'daily_rate' => $tier['daily'],
'pay_frequency' => 'semi_monthly',
'pay_group_id' => $payGroupId,
'is_exempt' => $index < 3,
'status' => 'active',
'created_by' => $ctx->userId,
]);
// Add earning items
foreach ($earningComponents as $component) {
$amount = match (true) {
str_contains(strtolower($component->name), 'basic') => $tier['gross'] * 0.50,
str_contains(strtolower($component->name), 'housing') ||
str_contains(strtolower($component->name), 'allowance') => $tier['gross'] * 0.15,
str_contains(strtolower($component->name), 'transport') => $tier['gross'] * 0.10,
default => $tier['gross'] * 0.05,
};
EmployeeSalaryItem::create([
'salary_structure_id' => $structure->id,
'salary_component_id' => $component->id,
'amount' => round($amount, 2),
]);
}
// Add deduction items
foreach ($deductionComponents as $component) {
$amount = match (true) {
str_contains(strtolower($component->name), 'sss') ||
str_contains(strtolower($component->name), 'social') => min($tier['gross'] * 0.045, 1350),
str_contains(strtolower($component->name), 'philhealth') ||
str_contains(strtolower($component->name), 'health') => $tier['gross'] * 0.025,
str_contains(strtolower($component->name), 'pagibig') ||
str_contains(strtolower($component->name), 'fund') => 200,
str_contains(strtolower($component->name), 'tax') ||
str_contains(strtolower($component->name), 'withholding') => max(0, ($tier['gross'] - 20833) * 0.15),
default => $tier['gross'] * 0.02,
};
if ($amount > 0) {
EmployeeSalaryItem::create([
'salary_structure_id' => $structure->id,
'salary_component_id' => $component->id,
'amount' => round($amount, 2),
]);
}
}
}
}
}