'월간', self::BILLING_YEARLY => '연간', self::BILLING_LIFETIME => '평생', ]; // ========================================================================= // 모델 설정 // ========================================================================= protected $fillable = [ 'name', 'code', 'description', 'price', 'billing_cycle', 'features', 'is_active', 'created_by', 'updated_by', 'deleted_by', ]; protected $casts = [ 'features' => 'array', 'is_active' => 'boolean', 'price' => 'float', ]; protected $attributes = [ 'is_active' => true, 'billing_cycle' => self::BILLING_MONTHLY, ]; // ========================================================================= // 스코프 // ========================================================================= /** * 활성 요금제만 */ public function scopeActive(Builder $query): Builder { return $query->where('is_active', true); } /** * 결제 주기별 필터 */ public function scopeOfCycle(Builder $query, string $cycle): Builder { return $query->where('billing_cycle', $cycle); } // ========================================================================= // 관계 // ========================================================================= public function subscriptions(): HasMany { return $this->hasMany(Subscription::class); } // ========================================================================= // 접근자 // ========================================================================= /** * 결제 주기 라벨 */ public function getBillingCycleLabelAttribute(): string { return self::BILLING_CYCLE_LABELS[$this->billing_cycle] ?? $this->billing_cycle; } /** * 포맷된 가격 */ public function getFormattedPriceAttribute(): string { return number_format($this->price).'원'; } /** * 활성 구독 수 */ public function getActiveSubscriptionCountAttribute(): int { return $this->subscriptions() ->where('status', Subscription::STATUS_ACTIVE) ->count(); } // ========================================================================= // 헬퍼 메서드 // ========================================================================= /** * 월 환산 가격 계산 */ public function getMonthlyPrice(): float { return match ($this->billing_cycle) { self::BILLING_YEARLY => round($this->price / 12, 2), self::BILLING_LIFETIME => 0, default => $this->price, }; } /** * 연 환산 가격 계산 */ public function getYearlyPrice(): float { return match ($this->billing_cycle) { self::BILLING_MONTHLY => $this->price * 12, self::BILLING_LIFETIME => 0, default => $this->price, }; } /** * 특정 기능 포함 여부 */ public function hasFeature(string $feature): bool { return in_array($feature, $this->features ?? [], true); } }