feat: [approval] 전자결재 모듈 API 구현
- 마이그레이션 4개 (approval_forms, approval_lines, approvals, approval_steps) - 모델 4개 (ApprovalForm, ApprovalLine, Approval, ApprovalStep) - ApprovalService 비즈니스 로직 (양식/결재선 CRUD, 기안함/결재함/참조함, 결재 액션) - 컨트롤러 3개 (ApprovalFormController, ApprovalLineController, ApprovalController) - FormRequest 13개 (양식/결재선/문서 검증) - Swagger 문서 3개 (26개 엔드포인트) - i18n 메시지/에러 키 추가 - 라우트 26개 등록
This commit is contained in:
320
app/Models/Tenants/Approval.php
Normal file
320
app/Models/Tenants/Approval.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Models\Members\User;
|
||||
use App\Traits\BelongsToTenant;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* 결재 문서 모델
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $tenant_id
|
||||
* @property string $document_number
|
||||
* @property int $form_id
|
||||
* @property string $title
|
||||
* @property array $content
|
||||
* @property string $status
|
||||
* @property int $drafter_id
|
||||
* @property \Carbon\Carbon|null $drafted_at
|
||||
* @property \Carbon\Carbon|null $completed_at
|
||||
* @property int $current_step
|
||||
* @property array|null $attachments
|
||||
* @property int|null $created_by
|
||||
* @property int|null $updated_by
|
||||
* @property int|null $deleted_by
|
||||
*/
|
||||
class Approval extends Model
|
||||
{
|
||||
use BelongsToTenant, SoftDeletes;
|
||||
|
||||
protected $table = 'approvals';
|
||||
|
||||
protected $casts = [
|
||||
'content' => 'array',
|
||||
'attachments' => 'array',
|
||||
'drafted_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
'current_step' => 'integer',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'document_number',
|
||||
'form_id',
|
||||
'title',
|
||||
'content',
|
||||
'status',
|
||||
'drafter_id',
|
||||
'drafted_at',
|
||||
'completed_at',
|
||||
'current_step',
|
||||
'attachments',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'status' => 'draft',
|
||||
'current_step' => 0,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 상태 상수
|
||||
// =========================================================================
|
||||
|
||||
public const STATUS_DRAFT = 'draft'; // 임시저장
|
||||
|
||||
public const STATUS_PENDING = 'pending'; // 결재 진행중
|
||||
|
||||
public const STATUS_APPROVED = 'approved'; // 승인 완료
|
||||
|
||||
public const STATUS_REJECTED = 'rejected'; // 반려
|
||||
|
||||
public const STATUS_CANCELLED = 'cancelled'; // 회수/취소
|
||||
|
||||
public const STATUSES = [
|
||||
self::STATUS_DRAFT,
|
||||
self::STATUS_PENDING,
|
||||
self::STATUS_APPROVED,
|
||||
self::STATUS_REJECTED,
|
||||
self::STATUS_CANCELLED,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 관계 정의
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 결재 양식
|
||||
*/
|
||||
public function form(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ApprovalForm::class, 'form_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 기안자
|
||||
*/
|
||||
public function drafter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'drafter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재 단계들
|
||||
*/
|
||||
public function steps(): HasMany
|
||||
{
|
||||
return $this->hasMany(ApprovalStep::class, 'approval_id')->orderBy('step_order');
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재자 단계들 (참조 제외)
|
||||
*/
|
||||
public function approverSteps(): HasMany
|
||||
{
|
||||
return $this->hasMany(ApprovalStep::class, 'approval_id')
|
||||
->whereIn('step_type', [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT])
|
||||
->orderBy('step_order');
|
||||
}
|
||||
|
||||
/**
|
||||
* 참조자 단계들
|
||||
*/
|
||||
public function referenceSteps(): HasMany
|
||||
{
|
||||
return $this->hasMany(ApprovalStep::class, 'approval_id')
|
||||
->where('step_type', ApprovalLine::STEP_TYPE_REFERENCE)
|
||||
->orderBy('step_order');
|
||||
}
|
||||
|
||||
/**
|
||||
* 생성자
|
||||
*/
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* 수정자
|
||||
*/
|
||||
public function updater(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 스코프
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 특정 상태
|
||||
*/
|
||||
public function scopeWithStatus($query, string $status)
|
||||
{
|
||||
return $query->where('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 임시저장
|
||||
*/
|
||||
public function scopeDraft($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_DRAFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재 진행중
|
||||
*/
|
||||
public function scopePending($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_PENDING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 승인 완료
|
||||
*/
|
||||
public function scopeApproved($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_APPROVED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 반려
|
||||
*/
|
||||
public function scopeRejected($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_REJECTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 완료됨 (승인 또는 반려)
|
||||
*/
|
||||
public function scopeCompleted($query)
|
||||
{
|
||||
return $query->whereIn('status', [self::STATUS_APPROVED, self::STATUS_REJECTED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 기안자
|
||||
*/
|
||||
public function scopeByDrafter($query, int $userId)
|
||||
{
|
||||
return $query->where('drafter_id', $userId);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 헬퍼 메서드
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 수정 가능 여부 (임시저장 상태만)
|
||||
*/
|
||||
public function isEditable(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 상신 가능 여부
|
||||
*/
|
||||
public function isSubmittable(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 승인/반려 가능 여부
|
||||
*/
|
||||
public function isActionable(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* 회수 가능 여부 (기안자만, 진행중 상태)
|
||||
*/
|
||||
public function isCancellable(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* 삭제 가능 여부 (임시저장만)
|
||||
*/
|
||||
public function isDeletable(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 상태 라벨
|
||||
*/
|
||||
public function getStatusLabelAttribute(): string
|
||||
{
|
||||
return match ($this->status) {
|
||||
self::STATUS_DRAFT => '임시저장',
|
||||
self::STATUS_PENDING => '진행',
|
||||
self::STATUS_APPROVED => '완료',
|
||||
self::STATUS_REJECTED => '반려',
|
||||
self::STATUS_CANCELLED => '회수',
|
||||
default => $this->status,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 결재자 확인
|
||||
*/
|
||||
public function getCurrentApproverStep(): ?ApprovalStep
|
||||
{
|
||||
return $this->steps()
|
||||
->whereIn('step_type', [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT])
|
||||
->where('status', ApprovalStep::STATUS_PENDING)
|
||||
->orderBy('step_order')
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 사용자가 현재 결재자인지 확인
|
||||
*/
|
||||
public function isCurrentApprover(int $userId): bool
|
||||
{
|
||||
$currentStep = $this->getCurrentApproverStep();
|
||||
|
||||
return $currentStep && $currentStep->approver_id === $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 사용자가 참조자인지 확인
|
||||
*/
|
||||
public function isReferee(int $userId): bool
|
||||
{
|
||||
return $this->referenceSteps()
|
||||
->where('approver_id', $userId)
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재 진행률
|
||||
*/
|
||||
public function getProgressAttribute(): array
|
||||
{
|
||||
$totalSteps = $this->approverSteps()->count();
|
||||
$completedSteps = $this->approverSteps()
|
||||
->whereIn('status', [ApprovalStep::STATUS_APPROVED, ApprovalStep::STATUS_REJECTED])
|
||||
->count();
|
||||
|
||||
return [
|
||||
'total' => $totalSteps,
|
||||
'completed' => $completedSteps,
|
||||
'percentage' => $totalSteps > 0 ? round(($completedSteps / $totalSteps) * 100) : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
133
app/Models/Tenants/ApprovalForm.php
Normal file
133
app/Models/Tenants/ApprovalForm.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Models\Members\User;
|
||||
use App\Traits\BelongsToTenant;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* 결재 양식 모델
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $tenant_id
|
||||
* @property string $name
|
||||
* @property string $code
|
||||
* @property string|null $category
|
||||
* @property array $template
|
||||
* @property bool $is_active
|
||||
* @property int|null $created_by
|
||||
* @property int|null $updated_by
|
||||
* @property int|null $deleted_by
|
||||
*/
|
||||
class ApprovalForm extends Model
|
||||
{
|
||||
use BelongsToTenant, SoftDeletes;
|
||||
|
||||
protected $table = 'approval_forms';
|
||||
|
||||
protected $casts = [
|
||||
'template' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'name',
|
||||
'code',
|
||||
'category',
|
||||
'template',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'is_active' => true,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 카테고리 상수
|
||||
// =========================================================================
|
||||
|
||||
public const CATEGORY_REQUEST = 'request'; // 품의서
|
||||
|
||||
public const CATEGORY_EXPENSE = 'expense'; // 지출결의서
|
||||
|
||||
public const CATEGORY_EXPENSE_ESTIMATE = 'expense_estimate'; // 지출 예상 내역서
|
||||
|
||||
public const CATEGORIES = [
|
||||
self::CATEGORY_REQUEST,
|
||||
self::CATEGORY_EXPENSE,
|
||||
self::CATEGORY_EXPENSE_ESTIMATE,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 관계 정의
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 이 양식으로 생성된 결재 문서들
|
||||
*/
|
||||
public function approvals(): HasMany
|
||||
{
|
||||
return $this->hasMany(Approval::class, 'form_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 scopeActive($query)
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 카테고리
|
||||
*/
|
||||
public function scopeCategory($query, string $category)
|
||||
{
|
||||
return $query->where('category', $category);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 헬퍼 메서드
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 카테고리 라벨
|
||||
*/
|
||||
public function getCategoryLabelAttribute(): string
|
||||
{
|
||||
return match ($this->category) {
|
||||
self::CATEGORY_REQUEST => '품의서',
|
||||
self::CATEGORY_EXPENSE => '지출결의서',
|
||||
self::CATEGORY_EXPENSE_ESTIMATE => '지출 예상 내역서',
|
||||
default => $this->category ?? '',
|
||||
};
|
||||
}
|
||||
}
|
||||
119
app/Models/Tenants/ApprovalLine.php
Normal file
119
app/Models/Tenants/ApprovalLine.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Models\Members\User;
|
||||
use App\Traits\BelongsToTenant;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* 결재선 템플릿 모델
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $tenant_id
|
||||
* @property string $name
|
||||
* @property array $steps
|
||||
* @property bool $is_default
|
||||
* @property int|null $created_by
|
||||
* @property int|null $updated_by
|
||||
* @property int|null $deleted_by
|
||||
*/
|
||||
class ApprovalLine extends Model
|
||||
{
|
||||
use BelongsToTenant, SoftDeletes;
|
||||
|
||||
protected $table = 'approval_lines';
|
||||
|
||||
protected $casts = [
|
||||
'steps' => 'array',
|
||||
'is_default' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'name',
|
||||
'steps',
|
||||
'is_default',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'is_default' => false,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 단계 유형 상수
|
||||
// =========================================================================
|
||||
|
||||
public const STEP_TYPE_APPROVAL = 'approval'; // 결재
|
||||
|
||||
public const STEP_TYPE_AGREEMENT = 'agreement'; // 합의
|
||||
|
||||
public const STEP_TYPE_REFERENCE = 'reference'; // 참조
|
||||
|
||||
public const STEP_TYPES = [
|
||||
self::STEP_TYPE_APPROVAL,
|
||||
self::STEP_TYPE_AGREEMENT,
|
||||
self::STEP_TYPE_REFERENCE,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 관계 정의
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 생성자
|
||||
*/
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* 수정자
|
||||
*/
|
||||
public function updater(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 스코프
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 기본 결재선만
|
||||
*/
|
||||
public function scopeDefault($query)
|
||||
{
|
||||
return $query->where('is_default', true);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 헬퍼 메서드
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 결재선 단계 수
|
||||
*/
|
||||
public function getStepCountAttribute(): int
|
||||
{
|
||||
return count($this->steps ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재자 목록 (user_id만)
|
||||
*/
|
||||
public function getApproverIdsAttribute(): array
|
||||
{
|
||||
return collect($this->steps ?? [])
|
||||
->pluck('user_id')
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
181
app/Models/Tenants/ApprovalStep.php
Normal file
181
app/Models/Tenants/ApprovalStep.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Models\Members\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
/**
|
||||
* 결재 단계 모델
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $approval_id
|
||||
* @property int $step_order
|
||||
* @property string $step_type
|
||||
* @property int $approver_id
|
||||
* @property string $status
|
||||
* @property string|null $comment
|
||||
* @property \Carbon\Carbon|null $acted_at
|
||||
* @property bool $is_read
|
||||
* @property \Carbon\Carbon|null $read_at
|
||||
*/
|
||||
class ApprovalStep extends Model
|
||||
{
|
||||
protected $table = 'approval_steps';
|
||||
|
||||
protected $casts = [
|
||||
'step_order' => 'integer',
|
||||
'acted_at' => 'datetime',
|
||||
'is_read' => 'boolean',
|
||||
'read_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'approval_id',
|
||||
'step_order',
|
||||
'step_type',
|
||||
'approver_id',
|
||||
'status',
|
||||
'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 STATUSES = [
|
||||
self::STATUS_PENDING,
|
||||
self::STATUS_APPROVED,
|
||||
self::STATUS_REJECTED,
|
||||
self::STATUS_SKIPPED,
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// 관계 정의
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 결재 문서
|
||||
*/
|
||||
public function approval(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Approval::class, 'approval_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 결재자/참조자
|
||||
*/
|
||||
public function approver(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approver_id');
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 스코프
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 대기 중
|
||||
*/
|
||||
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 => '건너뜀',
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user