'integer', 'sort_order' => 'integer', 'base_tariff' => 'decimal:2' ]; /** * Parent relationship (self-referencing) */ public function parent(): BelongsTo { return $this->belongsTo(BuildingFunction::class, 'parent_id'); } /** * Children relationship (self-referencing) */ public function children(): HasMany { return $this->hasMany(BuildingFunction::class, 'parent_id') ->orderBy('sort_order'); } /** * Parameters relationship (1:1) */ public function parameter(): HasOne { return $this->hasOne(BuildingFunctionParameter::class); } /** * Formulas relationship (1:n) - multiple formulas for different floor numbers */ public function formulas(): HasMany { return $this->hasMany(RetributionFormula::class)->orderBy('floor_number'); } /** * Get appropriate formula based on floor number */ public function getFormulaForFloor(int $floorNumber): ?RetributionFormula { return $this->formulas() ->where('floor_number', $floorNumber) ->first(); } /** * Retribution proposals relationship (1:n) */ public function retributionProposals(): HasMany { return $this->hasMany(RetributionProposal::class, 'building_function_id'); } /** * Scope: Parent functions only */ public function scopeParents($query) { return $query->whereNull('parent_id'); } /** * Scope: Children functions only */ public function scopeChildren($query) { return $query->whereNotNull('parent_id'); } /** * Scope: By level */ public function scopeByLevel($query, int $level) { return $query->where('level', $level); } /** * Check if building function has complete setup (parameters + at least one formula) */ public function hasCompleteSetup(): bool { return $this->parameter()->exists() && $this->formulas()->exists(); } /** * Get building function with all related data */ public function getCompleteData(): array { return [ 'id' => $this->id, 'code' => $this->code, 'name' => $this->name, 'description' => $this->description, 'level' => $this->level, 'sort_order' => $this->sort_order, 'base_tariff' => $this->base_tariff, 'parameters' => $this->parameter?->getParametersArray(), 'formulas' => $this->formulas->map(function ($formula) { return [ 'id' => $formula->id, 'name' => $formula->name, 'expression' => $formula->formula_expression, 'floor_number' => $formula->floor_number, 'floor_description' => $this->getFloorDescription($formula->floor_number) ]; })->toArray(), 'has_complete_setup' => $this->hasCompleteSetup() ]; } /** * Get floor description */ public function getFloorDescription(?int $floorNumber): string { if ($floorNumber === null || $floorNumber === 0) { return 'Semua lantai'; } return "Lantai {$floorNumber}"; } /** * Check if this is a parent function */ public function isParent(): bool { return $this->parent_id === null; } /** * Check if this is a child function */ public function isChild(): bool { return $this->parent_id !== null; } }