Files
sibedas/database/seeders/RetributionProposalSeeder.php
2025-06-18 02:54:41 +07:00

159 lines
7.1 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\RetributionProposal;
use App\Models\SpatialPlanning;
use App\Models\BuildingFunction;
use App\Models\RetributionFormula;
use App\Models\FloorHeightIndex;
use App\Models\BuildingFunctionParameter;
use Carbon\Carbon;
class RetributionProposalSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Get some sample data
$spatialPlannings = SpatialPlanning::take(5)->get();
$buildingFunctions = BuildingFunction::whereNotNull('parent_id')->get(); // Only child functions
if ($spatialPlannings->isEmpty() || $buildingFunctions->isEmpty()) {
$this->command->warn('No spatial plannings or building functions found. Please seed them first.');
return;
}
$sampleProposals = [
[
'spatial_planning_id' => $spatialPlannings->first()?->id,
'building_function_code' => 'HUNIAN_SEDERHANA',
'floor_number' => 2,
'floor_area' => 45666,
'total_building_area' => 91332, // 2 floors
'notes' => 'Sample calculation for Hunian Sederhana'
],
[
'spatial_planning_id' => $spatialPlannings->skip(1)->first()?->id,
'building_function_code' => 'USAHA_KECIL',
'floor_number' => 1,
'floor_area' => 150,
'total_building_area' => 150,
'notes' => 'Sample calculation for UMKM'
],
[
'spatial_planning_id' => null, // Testing nullable spatial_planning_id
'building_function_code' => 'CAMPURAN_KECIL',
'floor_number' => 3,
'floor_area' => 200,
'total_building_area' => 600,
'notes' => 'Sample calculation without spatial planning link'
]
];
foreach ($sampleProposals as $proposalData) {
$buildingFunction = BuildingFunction::where('code', $proposalData['building_function_code'])->first();
if (!$buildingFunction) {
$this->command->warn("Building function not found: {$proposalData['building_function_code']}");
continue;
}
// Get parameters
$parameters = BuildingFunctionParameter::where('building_function_id', $buildingFunction->id)->first();
$floorHeightIndex = FloorHeightIndex::where('floor_number', $proposalData['floor_number'])->first();
$retributionFormula = RetributionFormula::where('building_function_id', $buildingFunction->id)
->where('floor_number', $proposalData['floor_number'])
->first();
if (!$parameters || !$floorHeightIndex || !$retributionFormula) {
$this->command->warn("Missing data for building function: {$buildingFunction->name}");
continue;
}
// Calculate retribution using the Excel formula
$floorArea = $proposalData['floor_area'];
$fungsi_bangunan = $parameters->fungsi_bangunan;
$ip_permanen = $parameters->ip_permanen;
$ip_kompleksitas = $parameters->ip_kompleksitas;
$ip_ketinggian = $floorHeightIndex->ip_ketinggian;
$indeks_lokalitas = $parameters->indeks_lokalitas;
$base_value = 70350;
$additional_factor = 0.5;
// Step 1: Calculate H13 (floor coefficient)
$h13 = $fungsi_bangunan * ($ip_permanen + $ip_kompleksitas + (0.5 * $ip_ketinggian));
// Step 2: Main calculation
$main_calculation = 1 * $floorArea * ($indeks_lokalitas * $base_value * $h13 * 1);
// Step 3: Additional (50%)
$additional_calculation = $additional_factor * $main_calculation;
// Step 4: Total
$total_retribution = $main_calculation + $additional_calculation;
// Prepare calculation parameters and breakdown
$calculationParameters = [
'fungsi_bangunan' => $fungsi_bangunan,
'ip_permanen' => $ip_permanen,
'ip_kompleksitas' => $ip_kompleksitas,
'ip_ketinggian' => $ip_ketinggian,
'indeks_lokalitas' => $indeks_lokalitas,
'base_value' => $base_value,
'additional_factor' => $additional_factor,
'floor_area' => $floorArea
];
$calculationBreakdown = [
'h13_calculation' => [
'formula' => 'fungsi_bangunan * (ip_permanen + ip_kompleksitas + (0.5 * ip_ketinggian))',
'calculation' => "{$fungsi_bangunan} * ({$ip_permanen} + {$ip_kompleksitas} + (0.5 * {$ip_ketinggian}))",
'result' => $h13
],
'main_calculation' => [
'formula' => '1 * floor_area * (indeks_lokalitas * base_value * h13 * 1)',
'calculation' => "1 * {$floorArea} * ({$indeks_lokalitas} * {$base_value} * {$h13} * 1)",
'result' => $main_calculation
],
'additional_calculation' => [
'formula' => 'additional_factor * main_calculation',
'calculation' => "{$additional_factor} * {$main_calculation}",
'result' => $additional_calculation
],
'total_calculation' => [
'formula' => 'main_calculation + additional_calculation',
'calculation' => "{$main_calculation} + {$additional_calculation}",
'result' => $total_retribution
]
];
// Create the proposal
RetributionProposal::create([
'spatial_planning_id' => $proposalData['spatial_planning_id'],
'building_function_id' => $buildingFunction->id,
'retribution_formula_id' => $retributionFormula->id,
'floor_number' => $proposalData['floor_number'],
'floor_area' => $proposalData['floor_area'],
'total_building_area' => $proposalData['total_building_area'],
'ip_ketinggian' => $ip_ketinggian,
'floor_retribution_amount' => $total_retribution,
'total_retribution_amount' => $total_retribution, // For single floor, same as floor amount
'calculation_parameters' => $calculationParameters,
'calculation_breakdown' => $calculationBreakdown,
'notes' => $proposalData['notes'],
'calculated_at' => Carbon::now()
]);
$this->command->info("Created retribution proposal for: {$buildingFunction->name} - Floor {$proposalData['floor_number']}");
$this->command->info(" Amount: Rp " . number_format($total_retribution, 0, ',', '.'));
}
$this->command->info('Retribution Proposal seeding completed!');
$this->command->info('Total proposals created: ' . RetributionProposal::count());
}
}