- Document 모델 (상태 관리, 다형성 연결, 결재 처리) - DocumentApproval 모델 (결재 단계, 상태 처리) - DocumentData 모델 (EAV 패턴 데이터 저장) - DocumentAttachment 모델 (파일 첨부 연결) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
181 lines
4.2 KiB
PHP
181 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Documents;
|
|
|
|
use App\Models\Members\User;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
/**
|
|
* 문서 결재 모델
|
|
*
|
|
* @property int $id
|
|
* @property int $document_id
|
|
* @property int $user_id
|
|
* @property int $step 결재 순서
|
|
* @property string $role 역할 (작성/검토/승인)
|
|
* @property string $status 상태 (PENDING/APPROVED/REJECTED)
|
|
* @property string|null $comment 결재 의견
|
|
* @property \Carbon\Carbon|null $acted_at 결재 처리일
|
|
* @property int|null $created_by
|
|
* @property int|null $updated_by
|
|
* @property \Carbon\Carbon|null $created_at
|
|
* @property \Carbon\Carbon|null $updated_at
|
|
*/
|
|
class DocumentApproval extends Model
|
|
{
|
|
protected $table = 'document_approvals';
|
|
|
|
// =========================================================================
|
|
// 상태 상수
|
|
// =========================================================================
|
|
|
|
public const STATUS_PENDING = 'PENDING';
|
|
|
|
public const STATUS_APPROVED = 'APPROVED';
|
|
|
|
public const STATUS_REJECTED = 'REJECTED';
|
|
|
|
public const STATUSES = [
|
|
self::STATUS_PENDING,
|
|
self::STATUS_APPROVED,
|
|
self::STATUS_REJECTED,
|
|
];
|
|
|
|
// =========================================================================
|
|
// 역할 상수
|
|
// =========================================================================
|
|
|
|
public const ROLE_WRITER = '작성';
|
|
|
|
public const ROLE_REVIEWER = '검토';
|
|
|
|
public const ROLE_APPROVER = '승인';
|
|
|
|
// =========================================================================
|
|
// Fillable & Casts
|
|
// =========================================================================
|
|
|
|
protected $fillable = [
|
|
'document_id',
|
|
'user_id',
|
|
'step',
|
|
'role',
|
|
'status',
|
|
'comment',
|
|
'acted_at',
|
|
'created_by',
|
|
'updated_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'step' => 'integer',
|
|
'acted_at' => 'datetime',
|
|
];
|
|
|
|
protected $attributes = [
|
|
'step' => 1,
|
|
'status' => self::STATUS_PENDING,
|
|
];
|
|
|
|
// =========================================================================
|
|
// Relationships
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 문서
|
|
*/
|
|
public function document(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Document::class);
|
|
}
|
|
|
|
/**
|
|
* 결재자
|
|
*/
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
/**
|
|
* 생성자
|
|
*/
|
|
public function creator(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'created_by');
|
|
}
|
|
|
|
// =========================================================================
|
|
// Scopes
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 대기 중인 결재
|
|
*/
|
|
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 scopeForUser($query, int $userId)
|
|
{
|
|
return $query->where('user_id', $userId);
|
|
}
|
|
|
|
// =========================================================================
|
|
// Helper Methods
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 대기 상태 여부
|
|
*/
|
|
public function isPending(): bool
|
|
{
|
|
return $this->status === self::STATUS_PENDING;
|
|
}
|
|
|
|
/**
|
|
* 승인 상태 여부
|
|
*/
|
|
public function isApproved(): bool
|
|
{
|
|
return $this->status === self::STATUS_APPROVED;
|
|
}
|
|
|
|
/**
|
|
* 반려 상태 여부
|
|
*/
|
|
public function isRejected(): bool
|
|
{
|
|
return $this->status === self::STATUS_REJECTED;
|
|
}
|
|
|
|
/**
|
|
* 결재 처리 완료 여부
|
|
*/
|
|
public function isProcessed(): bool
|
|
{
|
|
return ! $this->isPending();
|
|
}
|
|
}
|