'integer', 'building_area' => 'decimal:2', 'retribution_amount' => 'decimal:2', 'calculation_detail' => 'array', 'calculated_at' => 'datetime' ]; /** * Building type relationship */ public function buildingType(): BelongsTo { return $this->belongsTo(BuildingType::class, 'building_type_id'); } /** * Generate unique calculation ID */ public static function generateCalculationId(): string { return 'RTB' . Carbon::now()->format('ymdHis') . rand(10, 99); } /** * Create new calculation */ public static function createCalculation( int $buildingTypeId, int $floorNumber, float $buildingArea, float $retributionAmount, array $calculationDetail ): self { return self::create([ 'calculation_id' => self::generateCalculationId(), 'building_type_id' => $buildingTypeId, 'floor_number' => $floorNumber, 'building_area' => $buildingArea, 'retribution_amount' => $retributionAmount, 'calculation_detail' => $calculationDetail, 'calculated_at' => Carbon::now() ]); } /** * Get formatted retribution amount */ public function getFormattedAmount(): string { return 'Rp ' . number_format($this->retribution_amount, 2, ',', '.'); } /** * Get calculation breakdown */ public function getCalculationBreakdown(): array { return $this->calculation_detail ?? []; } }