'datetime', 'completed_at' => 'datetime', ]; protected $attributes = [ 'status' => self::STATUS_DRAFT, ]; // ========================================================================= // Relationships // ========================================================================= /** * 템플릿 */ public function template(): BelongsTo { return $this->belongsTo(DocumentTemplate::class, 'template_id'); } /** * 결재 목록 */ public function approvals(): HasMany { return $this->hasMany(DocumentApproval::class)->orderBy('step'); } /** * 문서 데이터 */ public function data(): HasMany { return $this->hasMany(DocumentData::class); } /** * 첨부파일 */ public function attachments(): HasMany { return $this->hasMany(DocumentAttachment::class); } /** * 연결된 엔티티 (다형성) */ public function linkable(): MorphTo { return $this->morphTo(); } /** * 생성자 */ public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } /** * 수정자 */ public function updater(): BelongsTo { return $this->belongsTo(User::class, 'updated_by'); } // ========================================================================= // Scopes // ========================================================================= /** * 상태로 필터링 */ public function scopeStatus($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); } // ========================================================================= // Helper Methods // ========================================================================= /** * 편집 가능 여부 */ public function canEdit(): bool { return $this->status === self::STATUS_DRAFT || $this->status === self::STATUS_REJECTED; } /** * 결재 요청 가능 여부 */ public function canSubmit(): bool { return $this->status === self::STATUS_DRAFT || $this->status === self::STATUS_REJECTED; } /** * 결재 처리 가능 여부 */ public function canApprove(): bool { return $this->status === self::STATUS_PENDING; } /** * 취소 가능 여부 */ public function canCancel(): bool { return in_array($this->status, [ self::STATUS_DRAFT, self::STATUS_PENDING, ]); } /** * 현재 결재 단계 가져오기 */ public function getCurrentApprovalStep(): ?DocumentApproval { return $this->approvals() ->where('status', DocumentApproval::STATUS_PENDING) ->orderBy('step') ->first(); } /** * 특정 사용자의 결재 차례 확인 */ public function isUserTurn(int $userId): bool { $currentStep = $this->getCurrentApprovalStep(); return $currentStep && $currentStep->user_id === $userId; } }