'boolean', 'sort_order' => 'integer', ]; protected $attributes = [ 'type' => 'calculation', 'output_type' => 'variable', 'sort_order' => 0, 'is_active' => true, ]; // 수식 유형 상수 public const TYPE_INPUT = 'input'; public const TYPE_CALCULATION = 'calculation'; public const TYPE_RANGE = 'range'; public const TYPE_MAPPING = 'mapping'; // 출력 유형 상수 public const OUTPUT_VARIABLE = 'variable'; public const OUTPUT_ITEM = 'item'; // ========================================================================= // Relationships // ========================================================================= /** * 카테고리 관계 */ public function category(): BelongsTo { return $this->belongsTo(QuoteFormulaCategory::class, 'category_id'); } /** * 범위 규칙 */ public function ranges(): HasMany { return $this->hasMany(QuoteFormulaRange::class, 'formula_id') ->orderBy('sort_order'); } /** * 매핑 규칙 */ public function mappings(): HasMany { return $this->hasMany(QuoteFormulaMapping::class, 'formula_id') ->orderBy('sort_order'); } /** * 품목 출력 */ public function items(): HasMany { return $this->hasMany(QuoteFormulaItem::class, 'formula_id') ->orderBy('sort_order'); } /** * 생성자 */ 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 isCommon(): bool { return is_null($this->product_id); } /** * Scope: 공통 수식 */ public function scopeCommon(Builder $query): Builder { return $query->whereNull('product_id'); } /** * Scope: 특정 제품 수식 (공통 + 제품 전용) */ public function scopeForProduct(Builder $query, ?int $productId): Builder { return $query->where(function ($q) use ($productId) { $q->whereNull('product_id'); if ($productId) { $q->orWhere('product_id', $productId); } }); } /** * Scope: 활성화된 수식 */ public function scopeActive(Builder $query): Builder { return $query->where('is_active', true); } /** * Scope: 정렬 순서 */ public function scopeOrdered(Builder $query): Builder { return $query->orderBy('sort_order'); } /** * Scope: 유형별 필터 */ public function scopeOfType(Builder $query, string $type): Builder { return $query->where('type', $type); } // ========================================================================= // Helper Methods // ========================================================================= /** * 유형 레이블 조회 */ public function getTypeLabelAttribute(): string { return match ($this->type) { self::TYPE_INPUT => '입력값', self::TYPE_CALCULATION => '계산식', self::TYPE_RANGE => '범위별', self::TYPE_MAPPING => '매핑', default => $this->type, }; } /** * 출력 유형 레이블 조회 */ public function getOutputTypeLabelAttribute(): string { return match ($this->output_type) { self::OUTPUT_VARIABLE => '변수', self::OUTPUT_ITEM => '품목', default => $this->output_type, }; } }