'integer', 'expires_at' => 'datetime', 'completed_at' => 'datetime', ]; // === Relations === public function signers(): HasMany { return $this->hasMany(EsignSigner::class, 'contract_id'); } public function signFields(): HasMany { return $this->hasMany(EsignSignField::class, 'contract_id'); } public function auditLogs(): HasMany { return $this->hasMany(EsignAuditLog::class, 'contract_id'); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } // === Scopes === public function scopeStatus($query, string $status) { return $query->where('status', $status); } public function scopeActive($query) { return $query->whereNotIn('status', [ self::STATUS_CANCELLED, self::STATUS_EXPIRED, self::STATUS_REJECTED, ]); } // === Helpers === public function isExpired(): bool { return $this->expires_at && $this->expires_at->isPast(); } public function canSign(): bool { return in_array($this->status, [ self::STATUS_PENDING, self::STATUS_PARTIALLY_SIGNED, ]) && ! $this->isExpired(); } public function getNextSigner(): ?EsignSigner { return $this->signers() ->whereIn('status', [EsignSigner::STATUS_WAITING, EsignSigner::STATUS_NOTIFIED, EsignSigner::STATUS_AUTHENTICATED]) ->orderBy('sign_order') ->first(); } }