diff --git a/app/Console/Commands/CopyActivityQueue.php b/app/Console/Commands/CopyActivityQueue.php new file mode 100644 index 0000000..f631004 --- /dev/null +++ b/app/Console/Commands/CopyActivityQueue.php @@ -0,0 +1,127 @@ +rowActive() + ->first(); + + if ($processing) { + return; + } + + $process = ActivityCopy::where('status', SigdStatus::PENDING) + ->rowActive() + ->orderBy('created_at', 'asc') + ->first(); + + if (!$process) { + return; + } + + $process->update([ + 'executed_time' => now(), + 'status' => SigdStatus::PROSES, + ]); + + $this->createLogFile($process); + $this->logMessage('info', 'Salin data aktivitas untuk Tahun: ' . $process->to_year . ', dari sumber Tahun: ' . $process->from_year . ', id: ' . $process->id); + + try { + $isLocked = ActivityLock::isLocked($process->to_year); + if ($isLocked) { + $this->logMessage('warning', 'Salin data aktivitas untuk Tahun: ' . $process->to_year . ', dari sumber Tahun: ' . $process->from_year . ', id: ' . $process->id . ' sedang dikunci dan tidak dapat melakukan salin data.'); + + $process->update([ + 'finished_time' => now(), + 'status' => SigdStatus::GAGAL, + ]); + + return; + } + + $this->executeService($process); + + $process->update([ + 'finished_time' => now(), + 'status' => SigdStatus::SELESAI, + ]); + + $this->logMessage('info', 'Salin data aktivitas untuk Tahun: ' . $process->to_year . ', dari sumber Tahun: ' . $process->from_year . ', id: ' . $process->id . ' berhasil diselesaikan.'); + } catch (\Exception $e) { + $this->logMessage('error', 'Terjadi kesalahan saat proses salin data aktivitas, id: ' . $process->id . '. Error: ' . $e->getMessage()); + throw $e; + } + } + + private function createLogFile(ActivityCopy $process) + { + $logDirectory = storage_path('logs/copy/'); + + if (!File::exists($logDirectory)) { + File::makeDirectory($logDirectory, 0755, true); + } + + $logFileName = $logDirectory . $process->to_year . '_' . $process->from_year . '_' . $process->id . '.log'; + file_put_contents($logFileName, ''); + + $this->logFilePath = $logFileName; + } + + private function executeService($process) + { + $service = "\\App\\Services\\Tool\\CopyActivityService"; + + try { + $serviceClass = app($service); + if (method_exists($serviceClass, 'copyAllData')) { + $serviceClass->copyAllData($process->from_year, $process->to_year); + } else { + $this->logMessage('error', get_class($serviceClass) . " tidak memiliki method copyAllData."); + } + } catch (\Exception $e) { + $this->logMessage('error', "Error saat menjalankan " . get_class($serviceClass) . ": " . $e->getMessage()); + + $process->update([ + 'executed_time' => null, + 'finished_time' => null, + '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); + } + } +} diff --git a/app/Console/Commands/EmisiCalculationQueue.php b/app/Console/Commands/EmisiCalculationQueue.php new file mode 100644 index 0000000..a51c06e --- /dev/null +++ b/app/Console/Commands/EmisiCalculationQueue.php @@ -0,0 +1,214 @@ +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); + // } + } +} diff --git a/app/Console/Commands/EmisiCalculationQueue.php.bak b/app/Console/Commands/EmisiCalculationQueue.php.bak new file mode 100644 index 0000000..a51c06e --- /dev/null +++ b/app/Console/Commands/EmisiCalculationQueue.php.bak @@ -0,0 +1,214 @@ +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); + // } + } +} diff --git a/app/Console/Commands/ProdusenCalculateQueue.php b/app/Console/Commands/ProdusenCalculateQueue.php new file mode 100644 index 0000000..266ce00 --- /dev/null +++ b/app/Console/Commands/ProdusenCalculateQueue.php @@ -0,0 +1,124 @@ +rowActive()->first(); + + if ($processing) { + return; + } + + $process = ActivityProdusenCalculate::where('status', SigdStatus::PENDING) + ->rowActive()->orderBy('created_at', 'asc')->first(); + + if (!$process) { + return; + } + + $process->update([ + 'executed_time' => now(), + 'status' => SigdStatus::PROSES, + ]); + + $this->createLogFile($process); + $this->logMessage('info', 'Hitung Data dari Produsen untuk Tahun: ' . $process->inventory_year . ', id: ' . $process->id); + + try { + $isLocked = ActivityLock::isLocked($process->inventory_year); + if ($isLocked) { + $this->logMessage('warning', 'Hitung Data dari Produsen untuk Tahun: ' . $process->inventory_year . ', id: ' . $process->id . ' sedang dikunci dan tidak dapat melakukan Hitung Data dari Produsen.'); + + $process->update([ + 'finished_time' => now(), + 'status' => SigdStatus::GAGAL, + ]); + + return; + } + + $this->executeService($process); + + $process->update([ + 'finished_time' => now(), + 'status' => SigdStatus::SELESAI, + ]); + + $this->logMessage('info', 'Hitung Data dari Produsen untuk Tahun: ' . $process->inventory_year . ', id: ' . $process->id . ' berhasil diselesaikan.'); + } catch (\Exception $e) { + $this->logMessage('error', 'Terjadi kesalahan saat proses Hitung Data dari Produsen, id: ' . $process->id . '. Error: ' . $e->getMessage()); + throw $e; + } + } + + private function createLogFile(ActivityProdusenCalculate $process) + { + $logDirectory = storage_path('logs/produsen_calculate/'); + + if (!File::exists($logDirectory)) { + File::makeDirectory($logDirectory, 0755, true); + } + + $logFileName = $logDirectory . $process->to_year . '_' . $process->from_year . '_' . $process->id . '.log'; + file_put_contents($logFileName, ''); + + $this->logFilePath = $logFileName; + } + + private function executeService($process) + { + $service = "\\App\\Services\\Tool\\ProdusenCalculateService"; + + try { + $serviceClass = app($service); + if (method_exists($serviceClass, 'calculateAndSave')) { + $serviceClass->calculateAndSave($process->inventory_year); + } else { + $this->logMessage('error', get_class($serviceClass) . " tidak memiliki method calculateAndSave."); + } + } catch (\Exception $e) { + $this->logMessage('error', "Error saat menjalankan " . get_class($serviceClass) . ": " . $e->getMessage()); + + $process->update([ + 'executed_time' => null, + 'finished_time' => null, + '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); + } + } +} diff --git a/app/Enums/ActivityType.php b/app/Enums/ActivityType.php new file mode 100644 index 0000000..511dced --- /dev/null +++ b/app/Enums/ActivityType.php @@ -0,0 +1,42 @@ + 'Login', + self::INSERT_ACTIVITY_DATA => 'Input Data Aktivitas', + self::UPDATE_ACTIVITY_DATA => 'Ubah Data Aktivitas', + self::INSERT_METADATA => 'Input Metadata', + self::DELETE_METADATA => 'Hapus Metadata', + + //new case + self::LOCK_ACTIVITY_FORM => 'Kunci Data Aktivitas', + self::UNLOCK_ACTIVITY_FORM => 'Buka Kunci Data Aktivitas', + self::COPY_ACTIVITY_FORM => 'Salin Data Aktivitas', + self::CALCULATION_EMISI => 'Buat Form Kalkulasi Emisi', + self::PRODUSEN_CALCULATE => 'Hitung Data dari Produsen', + self::APPROVAL_KONSOLIDASI => 'Data Aktivitas Produsen telah disetujui', + self::DISSAPPROVAL_KONSOLIDASI => 'Data Aktivitas Produsen batal disetujui', + + }; + } +} diff --git a/app/Enums/FruitVegetableCategory.php b/app/Enums/FruitVegetableCategory.php new file mode 100644 index 0000000..aeefbf1 --- /dev/null +++ b/app/Enums/FruitVegetableCategory.php @@ -0,0 +1,74 @@ + [ + 'Residential buildings' => [ + 1 => (object)['gpc_code' => 'i_1_1', 'notation_key' => 'NE'], + 2 => (object)['gpc_code' => 'i_1_2', 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'i_1_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Commercial buildings & facilities' => [ + 1 => (object)['gpc_code' => ['i_2_1','i_6_1'], 'notation_key' => 'NE'], + 2 => (object)['gpc_code' => ['i_2_2','i_6_2'], 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => ['i_2_3','i_6_3'], 'notation_key' => 'NE'], // DEFAULT + ], + 'Institutional buildings & facilities' => [ + 1 => (object)['gpc_code' => 'ie', 'notation_key' => 'IE'], + 2 => (object)['gpc_code' => 'ie', 'notation_key' => 'IE'], + 3 => (object)['gpc_code' => 'ie', 'notation_key' => 'IE'], + 'info' => 'Included in Commercial Buildings and Facilities' + ], + 'Industrial buildings & facilities' => [ + 1 => (object)['gpc_code' => 'i_3_1', 'notation_key' => 'NE'], + 2 => (object)['gpc_code' => 'i_3_2', 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'i_3_3', 'notation_key' => 'NE'], + ], + 'Agriculture' => [ + 1 => (object)['gpc_code' => 'i_5_1', 'notation_key' => 'NO'], + 2 => (object)['gpc_code' => 'i_5_2', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'i_5_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Fugitive emissions' => [ + 1 => (object)['gpc_code' => 'i_8_1', 'notation_key' => 'C'], + 3 => (object)['gpc_code' => 'i_7_1', 'notation_key' => 'NO'], + ] + ], + self::TRANSPORTATION => [ + 'On-road' => [ + 1 => (object)['gpc_code' => 'ii_1_1', 'notation_key' => 'NE'], + 2 => (object)['gpc_code' => 'ii_1_2', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'ii_1_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Rail' => [ + 1 => (object)['gpc_code' => 'ii_2_1', 'notation_key' => 'IE'], + 2 => (object)['gpc_code' => 'ii_2_2', 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'ii_2_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Waterborne navigation' => [ + 1 => (object)['gpc_code' => 'ii_3_1', 'notation_key' => 'IE'], + 2 => (object)['gpc_code' => 'ii_3_2', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'ii_3_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Aviation' => [ + 1 => (object)['gpc_code' => 'ii_4_1', 'notation_key' => 'NO'], + 2 => (object)['gpc_code' => 'ii_4_2', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'ii_4_3', 'notation_key' => 'NE'], // DEFAULT + ], + 'Off-road' => [ + 1 => (object)['gpc_code' => 'ii_5_1', 'notation_key' => 'NO'], + 2 => (object)['gpc_code' => 'ii_5_2', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'ii_5_3', 'notation_key' => 'NE'], // DEFAULT + ], + ], + self::WASTE => [ + 'Solid waste disposal' => [ + 1 => (object)['gpc_code' => ['iii_1_1','iii_1_3'], 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'iii_1_3', 'notation_key' => 'NO'], + ], + 'Biological treatment' => [ + 1 => (object)['gpc_code' => ['iii_2_1','iii_2_3'], 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'iii_2_3', 'notation_key' => 'NO'], + ], + 'Incinerated and open burning' => [ + 1 => (object)['gpc_code' => ['iii_3_1','iii_3_3'], 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'iii_3_3', 'notation_key' => 'NE'], + ], + 'Wastewater' => [ + 1 => (object)['gpc_code' => ['iii_4_1','iii_4_3'], 'notation_key' => 'NE'], + 3 => (object)['gpc_code' => 'iii_4_3', 'notation_key' => 'NE'], + ], + ], + self::IPPU => [ + 'Industrial processes' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'iv_1', 'notation_key' => 'NE'], // DEFAULT + ], + 'Produce Use' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'iv_2', 'notation_key' => 'NE'], // DEFAULT + ], + ], + self::AFOLU => [ + 'Livestock' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'v_1', 'notation_key' => 'NE'], // DEFAULT + ], + 'Land Use' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'v_2', 'notation_key' => 'NE'], // DEFAULT + ], + 'Other AFOLU' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'v_3', 'notation_key' => 'NE'], // DEFAULT + ], + ], + self::GRID_SUPPLIED_ENERGY => [ + 'Electricity-only generation' => [ + 1 => (object)['gpc_code' => 'i_4_4', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + ], + 'CHP generation' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + ], + 'Heat/cold generation' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + ], + 'Local renewable generation' => [ + 1 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + 3 => (object)['gpc_code' => 'no', 'notation_key' => 'NO'], + ] + ], + }; + } + + public function getLabel(): string + { + return match ($this) { + self::STATIONARY_ENERGY => 'Stationary Energy', + self::TRANSPORTATION => 'Transportation', + self::WASTE => 'Waste', + self::IPPU => 'IPPU', + self::AFOLU => 'AFOLU', + self::GRID_SUPPLIED_ENERGY => 'Generation of grid-supplied energy', + }; + } + + public static function getAllData(): array + { + $data = []; + foreach (self::cases() as $case) { + $data[$case->getLabel()] = $case->getData(); + } + return $data; + } +} diff --git a/app/Enums/LandCategory.php b/app/Enums/LandCategory.php new file mode 100644 index 0000000..abd4cf9 --- /dev/null +++ b/app/Enums/LandCategory.php @@ -0,0 +1,37 @@ + 'Forest', + self::CROPLAND => 'Cropland', + self::GRASSLAND => 'Grassland', + self::WETLAND => 'Wetland', + self::SETTLEMENT => 'Settlement', + self::OTHERLAND => 'Otherland', + }; + } + + public static function getSubcategories(LandCategory $category): array + { + return match ($category) { + self::FOREST => ['hp', 'hs', 'hmp', 'hrp', 'ht', 'hms', 'hrs'], + self::CROPLAND => ['pk', 'pt', 'pc', 'sw', 'tr'], + self::GRASSLAND => ['b', 's', 'br'], + self::WETLAND => ['a', 'rw'], + self::SETTLEMENT => ['pm'], + self::OTHERLAND => ['t', 'aw', 'tm', 'bdr', 'tb'], + }; + } +} diff --git a/app/Enums/LandType.php b/app/Enums/LandType.php new file mode 100644 index 0000000..5d4fafc --- /dev/null +++ b/app/Enums/LandType.php @@ -0,0 +1,42 @@ +name === $code) { + return $case->value; // Return the description + } + } + + return '-'; // Return a default value if not found + } +} diff --git a/app/Enums/LingkupAksesData.php b/app/Enums/LingkupAksesData.php new file mode 100644 index 0000000..8e48f11 --- /dev/null +++ b/app/Enums/LingkupAksesData.php @@ -0,0 +1,26 @@ + 'Semua Data', + self::INTERNAL => 'Internal Instansi', + }; + } + + public static function getOptions(): array + { + $options = []; + foreach (self::cases() as $case) { + $options[$case->value] = $case->label(); + } + return $options; + } +} diff --git a/app/Enums/Sector.php b/app/Enums/Sector.php new file mode 100644 index 0000000..4cac97d --- /dev/null +++ b/app/Enums/Sector.php @@ -0,0 +1,37 @@ + strtolower(str_replace('_', '', $case->name)), + 'name' => $case->value + ]; + }, self::cases()); + } + + public static function getName(string $code): ?string + { + foreach (self::cases() as $case) { + if (strtolower(str_replace(' ', '_', $case->name)) === $code) { + return $case->value; + } + } + return null; + } +} diff --git a/app/Enums/SigdStatus.php b/app/Enums/SigdStatus.php new file mode 100644 index 0000000..6004157 --- /dev/null +++ b/app/Enums/SigdStatus.php @@ -0,0 +1,22 @@ + 'PENDING', + self::PROSES => 'PROSES', + self::SELESAI => 'SELESAI', + self::GAGAL => 'GAGAL', + }; + } +} diff --git a/app/Enums/TransportationCategory.php b/app/Enums/TransportationCategory.php new file mode 100644 index 0000000..39423c8 --- /dev/null +++ b/app/Enums/TransportationCategory.php @@ -0,0 +1,52 @@ +value => self::ON_ROAD->getCategories(), + self::WATERBORNE->value => self::WATERBORNE->getCategories(), + self::AVIATION->value => self::AVIATION->getCategories(), + default => [], + }; + } +} diff --git a/app/Enums/WsCategory.php b/app/Enums/WsCategory.php new file mode 100644 index 0000000..03503e2 --- /dev/null +++ b/app/Enums/WsCategory.php @@ -0,0 +1,41 @@ + '1A1a - Main Activity Electricity and Heat Production', + self::manufaktur => '1A2 - Manufacturing Industry and Construction', + self::transportasi => '1A3 - Transport', + self::komersial => '1A4a - Commercial / Institutional', + self::rumah_tangga => '1A5 - Non-specified', + + self::enteric_fermentation => '3A1 - Methane Emissions from Enteric Fermentation and Manure Management', + self::manure_mgmt => '3A2a - Manure Management:(CH4) from Manure Management Systems', + self::manure_mgmt_direct_n2o => '3A2b - Manure Management: Direct N2O Emissions from Manure Management Systems', + self::manure_mgmt_indirect_n2o => '3C6 - Indirect N2O Emissions from Manure Management', + }; + } + + public static function fromName(string $name){ + + return constant("self::$name"); + } +} diff --git a/app/Exports/CrfExport.php b/app/Exports/CrfExport.php new file mode 100644 index 0000000..328e12c --- /dev/null +++ b/app/Exports/CrfExport.php @@ -0,0 +1,105 @@ +sector = $sector; + $this->crfData = $crfData; + $this->worksheets = $worksheets; + } + + public function view(): View + { + return view('reports.crf.report', [ + 'sector' => $this->sector, + 'crfData' => $this->crfData, + 'worksheets' => $this->worksheets, + 'isExport' => true + ]); + } + + public function styles(Worksheet $sheet) + { + // Apply styles to the header rows + $tableStartRow = 6; + $tableHeaderRow = $tableStartRow; // + ($this->wsData->ws_header - 1); + $tableEndRow = $sheet->getHighestRow(); + $columnStart = 'A'; + $columnEnd = $sheet->getHighestColumn(); + + $sheet->getStyle('A1:A3')->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_LEFT], + ]); + + // Apply table header styles + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableHeaderRow)->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + ]); + + // Apply borders to the entire table + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Set dynamic column styles based on data + foreach ($sheet->getRowIterator() as $row) { + $rowIndex = $row->getRowIndex(); + + // Skip the header rows + if ($rowIndex >= $tableStartRow && $rowIndex <= $tableHeaderRow) { + continue; + } + + foreach ($row->getCellIterator() as $cell) { + $value = $cell->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + + // Check if value is numeric + if (is_numeric($value)) { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + + // Apply number formatting + // $cell->setValue($value); + $formatCode = floor($value) != $value ? '#,##0.0#' : '#,##0'; + $cell->getStyle()->getNumberFormat()->setFormatCode($formatCode); + } else { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); + } + } + } + + // Auto-fit columns + foreach (range('A', $sheet->getHighestColumn()) as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + + // // Style footer row + // $sheet->getStyle($columnStart . $tableEndRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + // 'font' => ['bold' => true], + // 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT], + // ]); + + return []; + } +} diff --git a/app/Exports/FormExport.php b/app/Exports/FormExport.php new file mode 100644 index 0000000..43b80f4 --- /dev/null +++ b/app/Exports/FormExport.php @@ -0,0 +1,192 @@ +data = $data; + $this->isTemplate = $data['isTemplate']; + $this->titleExcel = $data['titleExcel']; + $this->inventoryYear = $data['inventoryYear']; + + $this->instansi = $data['instansi']; + } + + public function collection() + { + // Fetch necessary data + $data = $this->data; + $formDetails = $data['formDetails']; + $unitsMap = $data['unitsMap']; + $activityFormDetails = $data['activityFormDetails']; + + $excelData = collect(); + + if (!$this->isTemplate) { + // Add title row + $titleRow = [$this->titleExcel]; + $excelData->push($titleRow); + $excelData->push(['']); + + // Add print date row + $tanggalCetakRow = ['Tanggal Cetak: ' . now()->format('Y-m-d')]; + $excelData->push($tanggalCetakRow); + $excelData->push(['']); + } + + // Add header row + $header = ['TAHUN']; + foreach ($formDetails as $detail) { + $activityName = $detail->activity ? $detail->activity->name : 'N/A'; + $unitCode = $unitsMap[$detail->unit_code]->code ?? ''; + $header[] = $activityName . "\n" . '(' . $unitCode . ')'; + } + $excelData->push($header); + + // Add data rows + $years = activityYearRange($this->inventoryYear); + foreach ($years as $year) { + $row = [$year]; + foreach ($formDetails as $detail) { + $activityValue = isset($activityFormDetails[$year]) + ? $activityFormDetails[$year] + ->where('activity_code', $detail->activity_code) + ->where('activity_unit_code', $detail->unit_code) + ->first()->activity_value ?? '' + : ''; + + $row[] = $activityValue; + } + $excelData->push($row); + } + + return $excelData; + } + + public function title(): string + { + return 'Template'; // Sheet name + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + // Set page properties + $event->sheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE); + $event->sheet->getPageSetup()->setFitToWidth(1); + $event->sheet->getPageSetup()->setFitToHeight(0); + $event->sheet->getPageMargins()->setTop(0.5); + $event->sheet->getPageMargins()->setBottom(0.5); + $event->sheet->getPageMargins()->setLeft(0.5); + $event->sheet->getPageMargins()->setRight(0.5); + $event->sheet->getPageSetup()->setPaperSize(PageSetup::PAPERSIZE_A4); + $event->sheet->getPageSetup()->setHorizontalCentered(true); + $event->sheet->getPageSetup()->setVerticalCentered(true); + + if (!$this->isTemplate) { + // Merge cells for title and print date + // $event->sheet->mergeCells('A1:' . $event->sheet->getHighestColumn() . '1'); + // $event->sheet->mergeCells('A3:' . $event->sheet->getHighestColumn() . '3'); + + $event->sheet->mergeCells('A1:' . 'S1'); + $event->sheet->mergeCells('A3:' . 'S3'); + } + + // Set alignment and make header row bold and centered + $headerRow = $this->isTemplate == 1 ? 'A1' : 'A5'; + $valueRow = $this->isTemplate == 1 ? 1 : 5; + $event->sheet->getStyle($headerRow . ':' . $event->sheet->getHighestColumn() . $valueRow) + ->applyFromArray([ + 'font' => [ + 'bold' => true, + ], + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER, + 'wrapText' => true, // Ensure wrap text is enabled for newlines + ], + ]); + + // Apply borders to the table + $event->sheet->getDelegate()->getStyle($headerRow . ':' . $event->sheet->getDelegate()->getHighestColumn() . $event->sheet->getDelegate()->getHighestRow()) + ->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Auto size columns starting from A onwards + $highestColumn = $event->sheet->getDelegate()->getHighestColumn(); + $columns = $this->generateColumnsRange('A', $highestColumn); + + $valueRow = $this->isTemplate == 1 ? '2' : '6'; + foreach ($columns as $column) { + $event->sheet->getDelegate()->getColumnDimension($column)->setAutoSize(true); + + // Apply number format to data columns (B onwards) + if ($column != 'A') { + $highestRow = $event->sheet->getDelegate()->getHighestRow($column); + for ($row = $valueRow; $row <= $highestRow; $row++) { + $cellValue = $event->sheet->getCell($column . $row)->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + if (!$this->isTemplate) { + if (is_numeric($cellValue)) { + $formatCode = floor($cellValue) != $cellValue ? '#,##0.0###############' : '#,##0'; + } + } + + $event->sheet->getStyle($column . $row)->getNumberFormat()->setFormatCode($formatCode); + } + + if ($this->isTemplate) { + $event->sheet->getStyle($column . '2:' . $column . $event->sheet->getDelegate()->getHighestRow()) + ->applyFromArray([ + 'fill' => [ + 'fillType' => Fill::FILL_SOLID, + 'color' => ['argb' => 'FFFFFF00'], + ], + ]); + } + } + } + }, + ]; + } + + function generateColumnsRange($start, $end) + { + $columns = []; + $current = $start; + + while ($current !== $end) { + $columns[] = $current; + $current++; + } + $columns[] = $end; + + return $columns; + } +} diff --git a/app/Exports/FormKehutananExport.php b/app/Exports/FormKehutananExport.php new file mode 100644 index 0000000..c00961a --- /dev/null +++ b/app/Exports/FormKehutananExport.php @@ -0,0 +1,188 @@ +data = $data; + $this->isTemplate = $data['isTemplate']; + $this->titleExcel = $data['titleExcel']; + $this->inventoryYear = $data['inventoryYear']; + } + + public function collection() + { + // Fetch necessary data + $data = $this->data; + $lands = $data['lands']; + // $unitsMap = $data['unitsMap']; + $activityFormDetails = $data['activityFormDetails']; + + $excelData = collect(); + + if (!$this->isTemplate) { + // Add title row + $titleRow = [$this->titleExcel]; + $excelData->push($titleRow); + $excelData->push(['']); + + // Add print date row + $tanggalCetakRow = ['Tanggal Cetak: ' . now()->format('Y-m-d')]; + $excelData->push($tanggalCetakRow); + $excelData->push(['']); + $excelData->push([$data['inventoryYear'] - 1]); + } + + // Add header row + $header = $this->isTemplate ? [''] : [$data['inventoryYear'] - 2]; + foreach ($lands as $land) { + $header[] = $land; + } + $excelData->push($header); + + // Add data rows + foreach ($lands as $land1) { + $row = [$land1]; + foreach ($lands as $land2) { + $activityValue = isset($activityFormDetails) + ? optional( + $activityFormDetails + ->where('activity_code', strtolower($land1 . '_' . $land2)) + ->first(), + )->activity_value + : ''; + $row[] = $activityValue; + } + $excelData->push($row); + } + + return $excelData; + } + + public function title(): string + { + return 'Template'; // Sheet name + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + // Set page properties + $event->sheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE); + $event->sheet->getPageSetup()->setFitToWidth(1); + $event->sheet->getPageSetup()->setFitToHeight(0); + $event->sheet->getPageMargins()->setTop(0.5); + $event->sheet->getPageMargins()->setBottom(0.5); + $event->sheet->getPageMargins()->setLeft(0.5); + $event->sheet->getPageMargins()->setRight(0.5); + $event->sheet->getPageSetup()->setPaperSize(PageSetup::PAPERSIZE_A4); + $event->sheet->getPageSetup()->setHorizontalCentered(true); + $event->sheet->getPageSetup()->setVerticalCentered(true); + + if (!$this->isTemplate) { + // Merge cells for title and print date + $event->sheet->mergeCells('A1:' . $event->sheet->getHighestColumn() . '1'); + $event->sheet->mergeCells('A3:' . $event->sheet->getHighestColumn() . '3'); + $event->sheet->mergeCells('A5:' . $event->sheet->getHighestColumn() . '5'); + + // Set A5 center and bold + $event->sheet->getStyle('A5')->applyFromArray([ + 'font' => [ + 'bold' => true, + ], + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER, + ], + ]); + } + + // Set alignment and make header row bold and centered + $headerRow = $this->isTemplate == 1 ? 'A1' : 'A5'; + $valueRow = $this->isTemplate == 1 ? 1 : 6; + $event->sheet->getStyle($headerRow . ':' . $event->sheet->getHighestColumn() . $valueRow) + ->applyFromArray([ + 'font' => [ + 'bold' => true, + ], + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER, + 'wrapText' => true, // Ensure wrap text is enabled for newlines + ], + ]); + + // Apply borders to the table + $event->sheet->getDelegate()->getStyle($headerRow . ':' . $event->sheet->getDelegate()->getHighestColumn() . $event->sheet->getDelegate()->getHighestRow()) + ->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Auto size columns starting from A onwards + foreach (range('A', $event->sheet->getDelegate()->getHighestColumn()) as $column) { + $event->sheet->getDelegate()->getColumnDimension($column)->setAutoSize(true); + } + + // Apply number format to data columns (B onwards) + $dataColumns = range('B', $event->sheet->getDelegate()->getHighestColumn()); + $valueRow = $this->isTemplate == 1 ? '2' : '7'; + foreach ($dataColumns as $column) { + $highestRow = $event->sheet->getDelegate()->getHighestRow($column); + for ($row = $valueRow; $row <= $highestRow; $row++) { + $cellValue = $event->sheet->getCell($column . $row)->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + if (!$this->isTemplate) { + if (is_numeric($cellValue)) { + $formatCode = floor($cellValue) != $cellValue ? '#,##0.0###############' : '#,##0'; + } + } + + $event->sheet->getStyle($column . $row)->getNumberFormat()->setFormatCode($formatCode); + } + } + + $event->sheet->getStyle('A' . $valueRow . ':A' . $event->sheet->getDelegate()->getHighestRow()) + ->applyFromArray([ + 'font' => [ + 'bold' => true, + ], + ]); + + if ($this->isTemplate) { + foreach ($dataColumns as $column) { + $event->sheet->getStyle($column . '2:' . $column . $event->sheet->getDelegate()->getHighestRow()) + ->applyFromArray([ + 'fill' => [ + 'fillType' => Fill::FILL_SOLID, + 'color' => ['argb' => 'FFFFFF00'], + ], + ]); + } + } + }, + ]; + } +} diff --git a/app/Exports/GcomCrfExport.php b/app/Exports/GcomCrfExport.php new file mode 100644 index 0000000..3c4e2dd --- /dev/null +++ b/app/Exports/GcomCrfExport.php @@ -0,0 +1,104 @@ +inventoryYear = $inventoryYear; + $this->activityYear = $activityYear; + $this->gpcData = $gpcData; + $this->gpc = $gpc; + } + + public function view(): View + { + return view('reports.gcom-crf.report', [ + 'inventoryYear' => $this->inventoryYear, + 'activityYear' => $this->activityYear, + 'gpcData' => $this->gpcData, + 'gpc' => $this->gpc, + 'isExport' => true + ]); + } + + public function styles(Worksheet $sheet) + { + $tableStartRow = 6; + $tableHeaderRow = $tableStartRow + 2; + $tableEndRow = $sheet->getHighestRow(); + $columnStart = 'A'; + $columnEnd = $sheet->getHighestColumn(); + + $sheet->getStyle('A1:A3')->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_LEFT], + ]); + $sheet->mergeCells('A1:' . $columnEnd . '1'); + $sheet->mergeCells('A2:' . $columnEnd . '2'); + $sheet->mergeCells('A3:' . $columnEnd . '3'); + + // Apply table header styles + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableHeaderRow)->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + ]); + + // Apply borders to the entire table + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Set dynamic column styles based on data + foreach ($sheet->getRowIterator() as $row) { + $rowIndex = $row->getRowIndex(); + + // Skip the header rows + if ($rowIndex >= $tableStartRow && $rowIndex <= $tableHeaderRow) { + continue; + } + + foreach ($row->getCellIterator() as $cell) { + $value = $cell->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + + if (is_numeric($value)) { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + + $formatCode = floor($value) != $value ? '#,##0.0#' : '#,##0'; + $cell->getStyle()->getNumberFormat()->setFormatCode($formatCode); + } else { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); + } + } + } + + // Auto-fit columns + foreach (range('A', $sheet->getHighestColumn()) as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + + // // Style footer row + // $sheet->getStyle($columnStart . $tableEndRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + // 'font' => ['bold' => true], + // 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT], + // ]); + + return []; + } +} diff --git a/app/Exports/GpcOutputExport.php b/app/Exports/GpcOutputExport.php new file mode 100644 index 0000000..ab762ba --- /dev/null +++ b/app/Exports/GpcOutputExport.php @@ -0,0 +1,119 @@ +inventoryYear = $inventoryYear; + $this->gpcOutputs = $gpcOutputs; + $this->gpcOutputRList = $gpcOutputRList; + } + + public function view(): View + { + return view('reports.gpc-output.report', [ + 'inventoryYear' => $this->inventoryYear, + 'gpcOutputs' => $this->gpcOutputs, + 'gpcOutputRList' => $this->gpcOutputRList, + 'isExport' => true + ]); + } + + public function styles(Worksheet $sheet) + { + $tableStartRow = 6; + $tableHeaderRow = $tableStartRow; + $tableEndRow = $sheet->getHighestRow(); + $columnStart = 'A'; + $columnEnd = $sheet->getHighestColumn(); + + $sheet->getStyle('A1:A3')->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_LEFT], + ]); + $sheet->mergeCells('A1:' . $columnEnd . '1'); + $sheet->mergeCells('A2:' . $columnEnd . '2'); + $sheet->mergeCells('A3:' . $columnEnd . '3'); + + // Apply table header styles + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableHeaderRow)->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + ]); + + // Apply borders to the entire table + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Set dynamic column styles based on data + foreach ($sheet->getRowIterator() as $row) { + $rowIndex = $row->getRowIndex(); + + // Skip the header rows + if ($rowIndex >= $tableStartRow && $rowIndex <= $tableHeaderRow) { + continue; + } + + foreach ($row->getCellIterator() as $cell) { + $value = $cell->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + + if (is_numeric($value)) { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + + $formatCode = floor($value) != $value ? '#,##0.0#' : '#,##0'; + $cell->getStyle()->getNumberFormat()->setFormatCode($formatCode); + } else { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); + } + } + } + + // Auto-fit columns + $highestColumn = $sheet->getHighestColumn(); + $columns = $this->generateColumnsRange('A', $highestColumn); + foreach ($columns as $column) { + $sheet->getColumnDimension($column)->setAutoSize(true); + } + + + // // Style footer row + // $sheet->getStyle($columnStart . $tableEndRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + // 'font' => ['bold' => true], + // 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT], + // ]); + + return []; + } + + function generateColumnsRange($start, $end) + { + $columns = []; + $current = $start; + + while ($current !== $end) { + $columns[] = $current; + $current++; + } + $columns[] = $end; + + return $columns; + } +} diff --git a/app/Exports/WorksheetExport.php b/app/Exports/WorksheetExport.php new file mode 100644 index 0000000..a357d67 --- /dev/null +++ b/app/Exports/WorksheetExport.php @@ -0,0 +1,105 @@ +wsData = $wsData; + $this->emisiData = $emisiData; + } + + public function view(): View + { + return view('reports.worksheet.report', [ + 'wsData' => $this->wsData, + 'emisiData' => $this->emisiData, + 'isExport' => true + ]); + } + + public function styles(Worksheet $sheet) + { + // Apply styles to the header rows + $tableStartRow = 6; + $tableHeaderRow = $tableStartRow + ($this->wsData->ws_header - 1); + $tableEndRow = $sheet->getHighestRow(); + $columnStart = 'A'; + $columnEnd = $sheet->getHighestColumn(); + + $sheet->getStyle('A1:A3')->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_LEFT], + ]); + $sheet->mergeCells('A1:' . $columnEnd . '1'); + $sheet->mergeCells('A2:' . $columnEnd . '2'); + $sheet->mergeCells('A3:' . $columnEnd . '3'); + + // Apply table header styles + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableHeaderRow)->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + ]); + + // Apply borders to the entire table + $sheet->getStyle($columnStart . $tableStartRow . ':' . $columnEnd . $tableEndRow)->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); + + // Set dynamic column styles based on data + foreach ($sheet->getRowIterator() as $row) { + $rowIndex = $row->getRowIndex(); + + // Skip the header rows + if ($rowIndex >= $tableStartRow && $rowIndex <= $tableHeaderRow) { + continue; + } + + foreach ($row->getCellIterator() as $cell) { + $value = $cell->getValue(); + $formatCode = NumberFormat::FORMAT_GENERAL; + + // Check if value is numeric + if (is_numeric($value)) { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + + // Apply number formatting + // $cell->setValue($value); + $formatCode = floor($value) != $value ? '#,##0.0###' : '#,##0'; + $cell->getStyle()->getNumberFormat()->setFormatCode($formatCode); + } else { + $cell->getStyle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); + } + } + } + + // Style footer row + // $footerRowStyle = $sheet->getStyle($columnStart . $tableEndRow . ':' . $columnEnd . $tableEndRow); + // $footerRowStyle->applyFromArray([ + // 'font' => ['bold' => true], + // ]); + // $sheet->getStyle($columnStart . $tableEndRow)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); + + // Auto-fit columns + foreach (range('A', $sheet->getHighestColumn()) as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + + return []; + } +} diff --git a/app/Helpers/FormulaEvaluator.php b/app/Helpers/FormulaEvaluator.php new file mode 100644 index 0000000..c387609 --- /dev/null +++ b/app/Helpers/FormulaEvaluator.php @@ -0,0 +1,56 @@ + 0 ? '' : ''; if ($access2) { $active2 = activeMenuClass($p2->module) ? 'mm-active' : ''; - $html .= '