Files
sam-api/app/Models/Tenants/Salary.php

178 lines
4.2 KiB
PHP
Raw Normal View History

<?php
namespace App\Models\Tenants;
use App\Models\Members\User;
use App\Traits\Auditable;
use App\Traits\BelongsToTenant;
use App\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* 급여 모델
*
* @property int $id
* @property int $tenant_id
* @property int $employee_id
* @property int $year
* @property int $month
* @property float $base_salary
* @property float $total_allowance
* @property float $total_overtime
* @property float $total_bonus
* @property float $total_deduction
* @property float $net_payment
* @property array|null $allowance_details
* @property array|null $deduction_details
* @property string|null $payment_date
* @property string $status
* @property int|null $created_by
* @property int|null $updated_by
* @property int|null $deleted_by
*/
class Salary extends Model
{
use Auditable, BelongsToTenant, ModelTrait, SoftDeletes;
protected $table = 'salaries';
protected $fillable = [
'tenant_id',
'employee_id',
'year',
'month',
'base_salary',
'total_allowance',
'total_overtime',
'total_bonus',
'total_deduction',
'net_payment',
'allowance_details',
'deduction_details',
'payment_date',
'status',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'base_salary' => 'decimal:2',
'total_allowance' => 'decimal:2',
'total_overtime' => 'decimal:2',
'total_bonus' => 'decimal:2',
'total_deduction' => 'decimal:2',
'net_payment' => 'decimal:2',
'allowance_details' => 'array',
'deduction_details' => 'array',
'payment_date' => 'date',
];
protected $attributes = [
'status' => 'scheduled',
'base_salary' => 0,
'total_allowance' => 0,
'total_overtime' => 0,
'total_bonus' => 0,
'total_deduction' => 0,
'net_payment' => 0,
];
// =========================================================================
// 관계 정의
// =========================================================================
/**
* 직원
*/
public function employee(): BelongsTo
{
return $this->belongsTo(User::class, 'employee_id');
}
/**
* 생성자
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
/**
* 수정자
*/
public function updater(): BelongsTo
{
return $this->belongsTo(User::class, 'updated_by');
}
/**
* 직원 프로필 (테넌트별)
* 주의: eager loading constrain 필요
* ->with(['employeeProfile' => fn($q) => $q->where('tenant_id', $tenantId)])
*/
public function employeeProfile(): HasOne
{
return $this->hasOne(TenantUserProfile::class, 'user_id', 'employee_id');
}
// =========================================================================
// 헬퍼 메서드
// =========================================================================
/**
* 지급 완료 여부
*/
public function isCompleted(): bool
{
return $this->status === 'completed';
}
/**
* 지급 예정 여부
*/
public function isScheduled(): bool
{
return $this->status === 'scheduled';
}
/**
* 상태 변경
*/
public function markAsCompleted(): void
{
$this->status = 'completed';
}
/**
* 상태 변경
*/
public function markAsScheduled(): void
{
$this->status = 'scheduled';
}
/**
* 실지급액 계산
*/
public function calculateNetPayment(): float
{
return $this->base_salary
+ $this->total_allowance
+ $this->total_overtime
+ $this->total_bonus
- $this->total_deduction;
}
/**
* 년월 표시
*/
public function getPeriodLabel(): string
{
return sprintf('%d년 %d월', $this->year, $this->month);
}
}