Files
sam-manage/app/Models/Approvals/ApprovalStep.php

151 lines
4.1 KiB
PHP
Raw Normal View History

<?php
namespace App\Models\Approvals;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ApprovalStep extends Model
{
protected $table = 'approval_steps';
protected $casts = [
'step_order' => 'integer',
'parallel_group' => 'integer',
'acted_at' => 'datetime',
'is_read' => 'boolean',
'read_at' => 'datetime',
];
protected $fillable = [
'approval_id',
'step_order',
'step_type',
'parallel_group',
'approver_id',
'acted_by',
'approver_name',
'approver_department',
'approver_position',
'status',
'approval_type',
'comment',
'acted_at',
'is_read',
'read_at',
];
protected $attributes = [
'status' => 'pending',
'is_read' => false,
];
// =========================================================================
// 상태 상수
// =========================================================================
public const STATUS_PENDING = 'pending';
public const STATUS_APPROVED = 'approved';
public const STATUS_REJECTED = 'rejected';
public const STATUS_SKIPPED = 'skipped';
public const STATUS_ON_HOLD = 'on_hold';
public const STATUSES = [
self::STATUS_PENDING,
self::STATUS_APPROVED,
self::STATUS_REJECTED,
self::STATUS_SKIPPED,
self::STATUS_ON_HOLD,
];
// =========================================================================
// 관계 정의
// =========================================================================
public function approval(): BelongsTo
{
return $this->belongsTo(Approval::class, 'approval_id');
}
public function approver(): BelongsTo
{
return $this->belongsTo(User::class, 'approver_id');
}
public function actedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'acted_by');
}
// =========================================================================
// 스코프
// =========================================================================
public function scopePending($query)
{
return $query->where('status', self::STATUS_PENDING);
}
public function scopeApproved($query)
{
return $query->where('status', self::STATUS_APPROVED);
}
public function scopeByApprover($query, int $userId)
{
return $query->where('approver_id', $userId);
}
public function scopeApprovalOnly($query)
{
return $query->whereIn('step_type', [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT]);
}
public function scopeReferenceOnly($query)
{
return $query->where('step_type', ApprovalLine::STEP_TYPE_REFERENCE);
}
// =========================================================================
// 헬퍼 메서드
// =========================================================================
public function isActionable(): bool
{
return $this->status === self::STATUS_PENDING
&& in_array($this->step_type, [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT]);
}
public function isReference(): bool
{
return $this->step_type === ApprovalLine::STEP_TYPE_REFERENCE;
}
public function getStatusLabelAttribute(): string
{
return match ($this->status) {
self::STATUS_PENDING => '대기',
self::STATUS_APPROVED => '승인',
self::STATUS_REJECTED => '반려',
self::STATUS_SKIPPED => '건너뜀',
self::STATUS_ON_HOLD => '보류',
default => $this->status,
};
}
public function getStepTypeLabelAttribute(): string
{
return match ($this->step_type) {
ApprovalLine::STEP_TYPE_APPROVAL => '결재',
ApprovalLine::STEP_TYPE_AGREEMENT => '합의',
ApprovalLine::STEP_TYPE_REFERENCE => '참조',
default => $this->step_type,
};
}
}