add spatial plannings retribution calculations
This commit is contained in:
159
database/seeders/RetributionProposalSeeder.php
Normal file
159
database/seeders/RetributionProposalSeeder.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user