Files
sam-manage/app/Models/Sales/TenantProspect.php
김보곤 e272f16357 feat: [database] codebridge DB connection 적용 (merge 후 재적용)
- 78개 MNG 전용 모델에 $connection = 'codebridge' 재적용
- config/database.php codebridge connection 포함
2026-03-07 11:28:47 +09:00

289 lines
6.4 KiB
PHP

<?php
namespace App\Models\Sales;
use App\Models\Tenants\Tenant;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
/**
* 영업파트너 영업권(명함등록) 모델
*/
class TenantProspect extends Model
{
use SoftDeletes;
protected $table = 'tenant_prospects';
public const STATUS_ACTIVE = 'active'; // 영업권 유효
public const STATUS_EXPIRED = 'expired'; // 영업권 만료
public const STATUS_CONVERTED = 'converted'; // 테넌트 전환 완료
public const STATUS_COMPLETED = 'completed'; // 영업 완료
public const VALIDITY_MONTHS = 2; // 영업권 유효기간 (개월)
public const COOLDOWN_MONTHS = 1; // 재등록 대기 기간 (개월)
protected $fillable = [
'business_number',
'company_name',
'ceo_name',
'contact_phone',
'contact_email',
'address',
'registered_by',
'business_card_path',
'id_card_path',
'bankbook_path',
'status',
'registered_at',
'expires_at',
'cooldown_ends_at',
'tenant_id',
'converted_at',
'converted_by',
'memo',
];
protected $casts = [
'registered_at' => 'datetime',
'expires_at' => 'datetime',
'cooldown_ends_at' => 'datetime',
'converted_at' => 'datetime',
];
/**
* 등록한 영업파트너
*/
public function registeredBy(): BelongsTo
{
return $this->belongsTo(User::class, 'registered_by');
}
/**
* 전환된 테넌트
*/
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class, 'tenant_id');
}
/**
* 전환 처리자
*/
public function convertedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'converted_by');
}
/**
* 영업권 유효 여부
*/
public function isActive(): bool
{
return $this->status === self::STATUS_ACTIVE && now()->lt($this->expires_at);
}
/**
* 영업권 만료 여부
*/
public function isExpired(): bool
{
return $this->status === self::STATUS_EXPIRED || now()->gte($this->expires_at);
}
/**
* 테넌트 전환 완료 여부
*/
public function isConverted(): bool
{
return $this->status === self::STATUS_CONVERTED;
}
/**
* 영업 완료 여부
*/
public function isCompleted(): bool
{
return $this->status === self::STATUS_COMPLETED;
}
/**
* 재등록 대기 중 여부
*/
public function isInCooldown(): bool
{
return $this->isExpired() && now()->lt($this->cooldown_ends_at);
}
/**
* 재등록 가능 여부
*/
public function canReRegister(): bool
{
return $this->isExpired() && now()->gte($this->cooldown_ends_at);
}
/**
* 상태 라벨
*/
public function getStatusLabelAttribute(): string
{
if ($this->isConverted()) {
return '계약완료';
}
if ($this->isCompleted()) {
return '완료';
}
if ($this->isActive()) {
return '영업중';
}
if ($this->isInCooldown()) {
return '대기중';
}
return '만료';
}
/**
* 상태 색상 (Tailwind CSS)
*/
public function getStatusColorAttribute(): string
{
if ($this->isConverted()) {
return 'bg-green-100 text-green-800';
}
if ($this->isCompleted()) {
return 'bg-emerald-100 text-emerald-800';
}
if ($this->isActive()) {
return 'bg-blue-100 text-blue-800';
}
if ($this->isInCooldown()) {
return 'bg-yellow-100 text-yellow-800';
}
return 'bg-gray-100 text-gray-800';
}
/**
* 남은 일수
*/
public function getRemainingDaysAttribute(): int
{
if (! $this->isActive()) {
return 0;
}
return max(0, now()->diffInDays($this->expires_at, false));
}
/**
* 명함 이미지 URL
*/
public function getBusinessCardUrlAttribute(): ?string
{
if (! $this->business_card_path) {
return null;
}
return Storage::disk('tenant')->url($this->business_card_path);
}
/**
* 명함 이미지 존재 여부
*/
public function hasBusinessCard(): bool
{
return $this->business_card_path && Storage::disk('tenant')->exists($this->business_card_path);
}
/**
* 신분증 이미지 존재 여부
*/
public function hasIdCard(): bool
{
return $this->id_card_path && Storage::disk('tenant')->exists($this->id_card_path);
}
/**
* 신분증 이미지 URL
*/
public function getIdCardUrlAttribute(): ?string
{
if (! $this->id_card_path) {
return null;
}
return Storage::disk('tenant')->url($this->id_card_path);
}
/**
* 통장사본 이미지 존재 여부
*/
public function hasBankbook(): bool
{
return $this->bankbook_path && Storage::disk('tenant')->exists($this->bankbook_path);
}
/**
* 통장사본 이미지 URL
*/
public function getBankbookUrlAttribute(): ?string
{
if (! $this->bankbook_path) {
return null;
}
return Storage::disk('tenant')->url($this->bankbook_path);
}
/**
* 스코프: 유효한 영업권
*/
public function scopeActive($query)
{
return $query->where('status', self::STATUS_ACTIVE)
->where('expires_at', '>', now());
}
/**
* 스코프: 만료된 영업권
*/
public function scopeExpired($query)
{
return $query->where(function ($q) {
$q->where('status', self::STATUS_EXPIRED)
->orWhere('expires_at', '<=', now());
});
}
/**
* 스코프: 전환 완료
*/
public function scopeConverted($query)
{
return $query->where('status', self::STATUS_CONVERTED);
}
/**
* 스코프: 특정 영업파트너의 영업권
*/
public function scopeByPartner($query, int $userId)
{
return $query->where('registered_by', $userId);
}
}