*/ protected $fillable = ['name', 'kbli', 'activities', 'area', 'location', 'number', 'date', 'no_tapak', 'no_skkl', 'no_ukl', 'building_function', 'sub_building_function', 'number_of_floors', 'land_area', 'site_bcr']; protected $casts = [ 'area' => 'decimal:6', 'land_area' => 'decimal:6', 'site_bcr' => 'decimal:6', 'number_of_floors' => 'integer', 'date' => 'date' ]; /** * Retribution calculation relationship (1:1) */ public function retributionCalculation(): HasOne { return $this->hasOne(RetributionCalculation::class); } /** * Building function relationship (if building_function becomes FK in future) */ public function buildingFunctionRelation(): BelongsTo { return $this->belongsTo(BuildingFunction::class, 'building_function_id'); } /** * Check if spatial planning has retribution calculation */ public function hasRetributionCalculation(): bool { return $this->retributionCalculation()->exists(); } /** * Get building function text for detection */ public function getBuildingFunctionText(): string { return $this->building_function ?? $this->activities ?? ''; } /** * Get area for calculation (prioritize area, fallback to land_area) */ public function getCalculationArea(): float { return (float) ($this->area ?? $this->land_area ?? 0); } /** * Scope: Without retribution calculation */ public function scopeWithoutRetributionCalculation($query) { return $query->whereDoesntHave('retributionCalculation'); } /** * Scope: With retribution calculation */ public function scopeWithRetributionCalculation($query) { return $query->whereHas('retributionCalculation'); } }