'decimal:4', 'is_active' => 'boolean', 'min_floor' => 'integer', 'max_floor' => 'integer', 'floor_level' => 'integer', 'priority' => 'integer', ]; /** * Relationship to BuildingFunction */ public function buildingFunction() { return $this->belongsTo(BuildingFunction::class, 'building_function_id'); } /** * Relationship to MasterFormula */ public function formula() { return $this->belongsTo(MasterFormula::class, 'formula_id'); } /** * Scope untuk konfigurasi aktif */ public function scopeActive($query) { return $query->where('is_active', true); } /** * Scope untuk mencari berdasarkan building function dan floor level */ public function scopeForBuildingAndFloor($query, $buildingFunctionId, $floorLevel) { return $query->where('building_function_id', $buildingFunctionId) ->where(function($q) use ($floorLevel) { $q->where('floor_level', $floorLevel) ->orWhere('floor_level', 0) // 0 = berlaku untuk semua lantai ->orWhere(function($qq) use ($floorLevel) { $qq->whereNotNull('min_floor') ->whereNotNull('max_floor') ->where('min_floor', '<=', $floorLevel) ->where('max_floor', '>=', $floorLevel); }); }) ->orderBy('priority', 'desc') ->orderBy('floor_level', 'desc'); // Prioritas: spesifik floor > range > semua lantai } /** * Method untuk mendapatkan formula yang tepat untuk building function dan floor tertentu */ public static function getFormulaForBuildingAndFloor($buildingFunctionId, $floorLevel) { return self::active() ->forBuildingAndFloor($buildingFunctionId, $floorLevel) ->with('formula') ->first(); } /** * Method untuk check apakah floor level masuk dalam range */ public function isFloorInRange($floorLevel) { // Jika floor_level = 0, berlaku untuk semua lantai if ($this->floor_level == 0) { return true; } // Jika ada specific floor level if ($this->floor_level == $floorLevel) { return true; } // Jika ada range min-max if (!is_null($this->min_floor) && !is_null($this->max_floor)) { return $floorLevel >= $this->min_floor && $floorLevel <= $this->max_floor; } return false; } }