sigd/app/Console/Commands/EmisiCalculationQueue.php

215 lines
7.6 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Calculation;
use App\Enums\SigdStatus;
use App\Models\ActivityLock;
use App\Models\ReferenceWs;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class EmisiCalculationQueue extends Command
{
protected $signature = 'calculation:process';
protected $description = 'Process for the worksheet emission calculation queue';
private $logFilePath;
public function __construct()
{
parent::__construct();
}
public function handle()
{
set_time_limit(0);
try {
$processing = Calculation::where('calculation_status', SigdStatus::PROSES)->rowActive()->first();
if ($processing) {
return;
}
$calculation = Calculation::where('calculation_status', SigdStatus::PENDING)
->rowActive()->orderBy('created_at', 'asc')->first();
if (!$calculation) {
// $this->logMessage('info', 'Semua kalkulasi emisi telah berhasil diselesaikan.');
return;
}
$calculation->update([
'executed_time' => now(),
'calculation_status' => SigdStatus::PROSES,
]);
$this->createLogFile($calculation);
$this->logMessage('info', 'Kalkulasi Emisi untuk Tahun Inventory: ' . $calculation->inventory_year . ', id: ' . $calculation->id);
$isLocked = ActivityLock::isLocked($calculation->inventory_year);
if ($isLocked) {
$this->logMessage('warning', 'Kalkulasi Emisi untuk Tahun Inventory: ' . $calculation->inventory_year . ', id: ' . $calculation->id . ' sedang dikunci dan tidak dapat melakukan kalkulasi.');
$calculation->update([
'finished_time' => now(),
'calculation_status' => SigdStatus::GAGAL,
]);
return;
}
if ($calculation->energy) $this->executeService('energy', $calculation);
if ($calculation->agriculture) $this->executeService('agriculture', $calculation);
if ($calculation->folu) $this->executeService('folu', $calculation);
if ($calculation->waste) $this->executeService('waste', $calculation);
if ($calculation->ippu) $this->executeService('ippu', $calculation);
// Execute Energy GPC emission calculation
$this->energyGPCCalc($calculation);
// Execute mapping IPCC to GPC
$this->gpcMapping($calculation);
$calculation->update([
'finished_time' => now(),
'calculation_status' => SigdStatus::SELESAI,
]);
$this->logMessage('info', 'Kalkulasi Emisi untuk Tahun Inventory: ' . $calculation->inventory_year . ', id: ' . $calculation->id . ' berhasil diselesaikan.');
} catch (Exception $e) {
$this->logMessage('error', 'Terjadi kesalahan saat kalkulasi emisi, id: ' . $calculation->id . '. Error: ' . $e->getMessage());
throw $e;
}
}
private function createLogFile(Calculation $calculation)
{
$logDirectory = storage_path('logs/calculation/');
$this->logMessage('info', 'Checking if log directory exists: ' . $logDirectory);
if (!File::exists($logDirectory)) {
$this->logMessage('info', 'Directory not found. Creating directory: ' . $logDirectory);
File::makeDirectory($logDirectory, 0755, true);
}
$logFileName = $logDirectory . $calculation->inventory_year . '_' . $calculation->id . '.log';
file_put_contents($logFileName, '');
$this->logFilePath = $logFileName;
$this->logMessage('info', 'Log file created: ' . $logFileName);
}
private function executeService($sector, $calculation)
{
// if ($calculation->$sector) {
$wsList = ReferenceWs::where('sector', $sector)
->whereNotNull('code')->rowActive()->get();
foreach ($wsList as $ws) {
if ($ws->code == '4d1_ef') {
continue;
}
$service = "\\App\\Services\\Emisi\\" . class_basename($ws->model) . "Service";
$this->logMessage('service yang dijalankan', "{$service}");
try {
$serviceClass = app($service);
if (method_exists($service, 'save')) {
$serviceClass->save($ws->code, $calculation->inventory_year);
$this->logMessage('info', "Kalkulasi Emisi pada Worksheet {$ws->ws_code}. {$ws->ws_title} telah berhasil diselesaikan.");
} else {
$this->logMessage('error', "{$service} tidak memiliki method proses kalkulasi.");
}
} catch (\Exception $e) {
$this->logMessage('error', "Error saat menjalankan {$service} pada sektor {$sector}: " . $e->getMessage());
$calculation->update([
'executed_time' => null,
'finished_time' => null,
'calculation_status' => SigdStatus::PENDING,
]);
throw $e;
}
}
// }
}
private function gpcMapping($calculation)
{
$service = "\\App\\Services\\Emisi\\GpcMappingService";
try {
$serviceClass = app($service);
if (method_exists($service, 'save')) {
$serviceClass->save($calculation->inventory_year);
$this->logMessage('info', "Mapping dari Emisi IPCC ke GPC telah berhasil diproses");
} else {
$this->logMessage('error', get_class($serviceClass) . " tidak memiliki method save.");
}
} catch (\Exception $e) {
$this->logMessage('error', "Error saat menjalankan " . get_class($serviceClass) . ": " . $e->getMessage());
$calculation->update([
'executed_time' => null,
'finished_time' => null,
'calculation_status' => SigdStatus::PENDING,
]);
throw $e;
}
}
private function energyGPCCalc($calculation)
{
$service = "\\App\\Services\\Emisi\\EnergyGPCService";
try {
$serviceClass = app($service);
if (method_exists($service, 'save')) {
$serviceClass->save($calculation->inventory_year);
$this->logMessage('info', "Kalkulasi Emisi Energi GPC telah berhasil diproses");
} else {
$this->logMessage('error', get_class($serviceClass) . " tidak memiliki method save.");
}
} catch (\Exception $e) {
$this->logMessage('error', "Error saat menjalankan " . get_class($serviceClass) . ": " . $e->getMessage());
$calculation->update([
'executed_time' => null,
'finished_time' => null,
'calculation_status' => SigdStatus::PENDING,
]);
throw $e;
}
}
private function logMessage($level, $message)
{
$this->line($message); // Output to console
// Log to the file
$formattedMessage = '[' . now() . '] ' . strtoupper($level) . ': ' . $message . PHP_EOL;
if ($this->logFilePath) {
file_put_contents($this->logFilePath, $formattedMessage, FILE_APPEND);
}
$this->info($message);
// Also log to Laravel's default log channel
if ($level === 'error') {
Log::error($message);
}
// } else {
// Log::info($message);
// }
}
}