sigd/app/Services/Emisi/GpcMappingService.php

234 lines
8.5 KiB
PHP

<?php
namespace App\Services\Emisi;
use App\Models\ActivityCrf;
use App\Models\ActivityFormDetail;
use App\Models\ActivityGpc;
use App\Models\ActivityGpcOutput;
use App\Models\Energy1A;
use App\Models\EnergyPLN;
use App\Models\ReferenceEf;
use App\Models\ReferenceGpc;
use App\Enums\TransportationCategory;
use App\Services\SigdCrudService;
class GpcMappingService extends SigdCrudService
{
public function __construct(ActivityGpcOutput $model)
{
$this->model = $model;
}
public function save($inventoryYear)
{
try {
$dataBatch = [];
$years = activityYearRange($inventoryYear);
foreach ($years as $year) {
$dataBatch = array_merge($dataBatch, $this->calcAndSave($inventoryYear, $year));
}
return $dataBatch;
} catch (\Exception $e) {
throw $e;
}
}
private function calcPlnEmission($inventoryYear, $activityYear)
{
$dataForms = [];
$activities = [];
$sectorCode = 'energy';
$formCode = 'pln';
try {
// Initialize activities
$formSetting = $this->getDataSettingFormDetail($sectorCode, $formCode);
foreach ($formSetting as $row) $activities[$row->activity_code] = 0;
// Get data activities
$formActivity = $this->getActivityFormDetailsByYear($inventoryYear, $activityYear, $sectorCode, $formCode);
foreach ($formActivity as $row) $activities[$row->activity_code] = $row->activity_value ?? 0;
$ef_listrik_terkoreksi = $activities['ef_listrik_terkoreksi'];
$no = 1;
foreach ($activities as $activity => $value) {
if ($activity != 'ef_listrik_terkoreksi') {
$co2_ton = $value * $ef_listrik_terkoreksi;
$co2_gg = $co2_ton / 1000;
$dataForm = [
'inventory_year' => $inventoryYear,
'activity_year' => $activityYear,
'activity_code' => $activity,
'value' => $value,
'ef_listrik_terkoreksi' => $ef_listrik_terkoreksi,
'co2_ton' => $co2_ton,
'co2_gg' => $co2_gg,
'row_num' => $no++,
];
$this->createOrUpdate([
'inventory_year' => $inventoryYear,
'activity_year' => $activityYear,
'activity_code' => $activity,
'row_status' => 1,
], $dataForm, EnergyPLN::class);
$dataForms[] = $dataForm;
}
}
} catch (\Exception $e) {
throw $e;
}
}
private function getDataGpcList()
{
$query = ReferenceGpc::rowActive()->orderByRowNum()->get();
return $query;
}
public function calcAndSave($inventoryYear, $activityYear)
{
$dataForms = [];
$activities = [];
try {
$this->calcPlnEmission($inventoryYear, $activityYear);
// Get data activities
$formActivity = $this->getActivityFormDetailsByYear($inventoryYear, $activityYear, 'waste', 'kependudukan');
foreach ($formActivity as $row) $activities[$row->activity_code] = $row->activity_value ?? 0;
$gpc_output['inventory_year'] = $inventoryYear;
$gpc_output['activity_year'] = $activityYear;
$gpc_output['population'] = $activities['jumlah_penduduk'] ?? 0;
$gpc_output['area'] = $activities['luas_wilayah'] ?? 0;
$gpc_output['gdp'] = $activities['pdb'] ?? 0;
$gpcList = $this->getDataGpcList();
foreach ($gpcList as $gpc) {
$columnName = strtolower(str_replace('.', '_', $gpc->gpc_code));
$gpc_output[$columnName] = null;
// Handle PLN listrik sector
if (strpos($gpc->sub_sector, 'pln_listrik_') === 0) {
list(, $activityCode) = explode('_', $gpc->sub_sector, 2);
$pln = EnergyPLN::rowActive()
->where('activity_code', $activityCode)
->where('inventory_year', $inventoryYear)
->where('activity_year', $activityYear)
->first();
$gpc_output[$columnName] = $pln->co2_gg ?? null;
continue;
}
// Handle transportation sector
if ($gpc->sector === 'transportation' && $gpc->sub_sector !== null) {
$transCategories = TransportationCategory::getTransportationCategories($gpc->sub_sector);
$activities = Energy1A::rowActive()->where('category', $gpc->ipcc_code)
->where('inventory_year', $inventoryYear)->where('activity_year', $activityYear)
->whereIn('activity_code', $transCategories)->get();
$co2eq = $this->calculateCO2eq($activities);
$gpc_output[$columnName] = $co2eq ?? null;
continue;
}
// Handle CRF (3A, 3B, 3C) related IPCC codes
if (!is_null($gpc->ipcc_code)) {
if (in_array($gpc->ipcc_code, ['3A', '3B', '3C'])) {
$gpc_output[$columnName] = $this->getCrfSumForCode($gpc->ipcc_code, $inventoryYear, $activityYear);
} else {
$crf = ActivityCrf::rowActive()->where('ws_code', $gpc->ipcc_code)
->where('inventory_year', $inventoryYear)->where('activity_year', $activityYear)
->first();
$gpc_output[$columnName] = $crf->co2eq ?? null;
}
continue;
}
// Handle energy_gpc sector
if ($gpc->sector === 'energy_gpc') {
$gpc_output[$columnName] = $this->getEnergyGpcValue($columnName, $gpc, $inventoryYear, $activityYear);
}
}
$this->createOrUpdate([
'inventory_year' => $inventoryYear,
'activity_year' => $activityYear,
'row_status' => 1,
], $gpc_output);
$dataForms[] = $gpc_output;
return $dataForms;
} catch (\Exception $e) {
throw $e;
}
}
private function calculateCO2eq($activities)
{
$co2 = $activities->sum('emission_co2');
$ch4 = $activities->sum('emission_ch4');
$n2o = $activities->sum('emission_n2o');
$gwp = $this->getGWPValues();
return ($co2 ? $co2 * $gwp['CO2']->value : 0) +
($ch4 ? $ch4 * $gwp['CH4']->value : 0) +
($n2o ? $n2o * $gwp['N2O']->value : 0);
}
// Helper function to handle CRF code 3A, 3B, 3C queries
private function getCrfSumForCode($ipccCode, $inventoryYear, $activityYear)
{
$crfQuery = ActivityCrf::rowActive()->where('inventory_year', $inventoryYear)->where('activity_year', $activityYear);
if ($ipccCode == '3B') {
$crfQuery->where('ws_code', 'like', '3B%')->orWhere('ws_code', '3C1');
} elseif ($ipccCode == '3C') {
$crfQuery->where('ws_code', 'like', '3C%')->where('ws_code', '!=', '3C1');
} else {
$crfQuery->where('ws_code', 'like', '3A%');
}
return $crfQuery->sum('co2eq') ?: null;
}
// Helper function to handle energy_gpc values based on gpc code and subsector
private function getEnergyGpcValue($gpcCode, $gpc, $inventoryYear, $activityYear)
{
if ($gpcCode == 'i_4_1') {
$gpcQ = ActivityGpc::rowActive()->where('gpc_code', $gpcCode)
->where('inventory_year', $inventoryYear)->where('activity_year', $activityYear)
->first();
return (float)$gpcQ->co2eq != 0.0 ? $gpcQ->co2eq :
ActivityFormDetail::getValue($inventoryYear, $activityYear, $gpc->sector, 'penyulingan', 'emisi_minyak_mentah') ?? null;
}
if (in_array($gpcCode, ['i_7_1', 'i_8_1'])) {
return ActivityFormDetail::getValue($inventoryYear, $activityYear, $gpc->sector, $gpc->sub_sector, 'emisi') ?? null;
}
$crf = ActivityGpc::rowActive()
->where('sector', $gpc->sector)->where('gpc_code', $gpcCode)
->where('inventory_year', $inventoryYear)->where('activity_year', $activityYear)
->first();
return $crf->co2eq ?? null;
}
}