feat: 급여 관리 API 및 더미 시더 확장
- 급여 관리 API 추가 (SalaryController, SalaryService, Salary 모델) - 급여 목록/상세/등록/수정/삭제 - 상태 변경 (scheduled/completed) - 일괄 상태 변경 - 통계 조회 - 더미 시더 확장 - 근태, 휴가, 부서, 사용자 시더 추가 - 기존 시더 tenant_id/created_by/updated_by 필드 추가 - 부서 서비스 개선 (tree 조회 기능 추가) - 카드 서비스 수정 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,18 @@ class User extends Authenticatable
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'has_account',
|
||||
];
|
||||
|
||||
/**
|
||||
* 시스템 계정(비밀번호) 보유 여부
|
||||
*/
|
||||
public function getHasAccountAttribute(): bool
|
||||
{
|
||||
return ! empty($this->password);
|
||||
}
|
||||
|
||||
public function userTenants()
|
||||
{
|
||||
return $this->hasMany(UserTenant::class);
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
class Department extends Model
|
||||
{
|
||||
use HasRoles, ModelTrait; // 부서도 권한/역할을 가짐
|
||||
use HasRoles, ModelTrait, SoftDeletes; // 부서도 권한/역할을 가짐
|
||||
|
||||
protected $table = 'departments';
|
||||
|
||||
|
||||
165
app/Models/Tenants/Salary.php
Normal file
165
app/Models/Tenants/Salary.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Models\Members\User;
|
||||
use App\Traits\BelongsToTenant;
|
||||
use App\Traits\ModelTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
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 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');
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 헬퍼 메서드
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 지급 완료 여부
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user