199 lines
7.0 KiB
PHP
199 lines
7.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Livewire;
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Livewire\Component;
|
|
|
|
class Reports extends Component
|
|
{
|
|
public function render()
|
|
{
|
|
return view('livewire.reports');
|
|
}
|
|
|
|
/**
|
|
* Decode and validate a base64 chart image string.
|
|
* Returns the raw image bytes, or throws if the content is not a PNG or JPEG.
|
|
*/
|
|
private function decodeChartImage(string $chartImage): string
|
|
{
|
|
$base64Data = explode(',', $chartImage)[1] ?? $chartImage;
|
|
$imageData = base64_decode($base64Data, strict: true);
|
|
|
|
if ($imageData === false) {
|
|
abort(422, 'Invalid chart image data');
|
|
}
|
|
|
|
// Validate magic bytes — must be PNG (\x89PNG) or JPEG (\xFF\xD8\xFF)
|
|
$isPng = str_starts_with($imageData, "\x89PNG");
|
|
$isJpeg = str_starts_with($imageData, "\xFF\xD8\xFF");
|
|
|
|
if (!$isPng && !$isJpeg) {
|
|
Log::warning('Reports: rejected chart image with invalid magic bytes', [
|
|
'guard' => session('activeProfileType'),
|
|
'profileId' => session('activeProfileId'),
|
|
]);
|
|
abort(422, 'Chart image must be a PNG or JPEG');
|
|
}
|
|
|
|
return $imageData;
|
|
}
|
|
|
|
public function exportPdfWithChart($chartImage, $fromDate = null, $toDate = null)
|
|
{
|
|
abort_unless(Auth::check(), 403);
|
|
|
|
Log::info('Reports::exportPdfWithChart called', [
|
|
'chartImageLength' => strlen($chartImage),
|
|
'fromDate' => $fromDate,
|
|
'toDate' => $toDate
|
|
]);
|
|
|
|
// Generate unique filename for temporary chart image
|
|
$chartImageId = uniqid('chart_', true);
|
|
$tempImagePath = storage_path('app/temp/' . $chartImageId . '.png');
|
|
|
|
// Ensure temp directory exists
|
|
if (!file_exists(dirname($tempImagePath))) {
|
|
mkdir(dirname($tempImagePath), 0755, true);
|
|
}
|
|
|
|
// Decode and validate image content before writing
|
|
$imageData = $this->decodeChartImage($chartImage);
|
|
file_put_contents($tempImagePath, $imageData);
|
|
|
|
Log::info('Chart image saved to temp file', [
|
|
'chartImageId' => $chartImageId,
|
|
'fileSize' => strlen($imageData)
|
|
]);
|
|
|
|
// Store only the chart image ID in session (much smaller)
|
|
session(['chart_image_id' => $chartImageId]);
|
|
|
|
// Build URL with current report parameters - use passed dates or fallback
|
|
$params = [
|
|
'fromDate' => $fromDate ?? request()->get('fromDate'),
|
|
'toDate' => $toDate ?? request()->get('toDate'),
|
|
'with_chart' => 1,
|
|
'decimal' => request()->get('decimal', 0),
|
|
];
|
|
|
|
$url = route('reports.pdf', $params);
|
|
Log::info('PDF URL generated', ['url' => $url]);
|
|
|
|
// Use JavaScript to open PDF in new window/tab
|
|
$this->dispatch('openPdf', $url);
|
|
}
|
|
|
|
public function exportPdf()
|
|
{
|
|
Log::info('Reports::exportPdf called - delegating to SingleReport');
|
|
|
|
// This method should delegate to SingleReport component
|
|
// For now, just use basic parameters
|
|
$params = [
|
|
'fromDate' => request()->get('fromDate'),
|
|
'toDate' => request()->get('toDate'),
|
|
'decimal' => request()->get('decimal', 0),
|
|
];
|
|
|
|
$url = route('reports.pdf', $params);
|
|
Log::info('PDF URL generated from Reports component', ['url' => $url]);
|
|
$this->dispatch('openPdf', $url);
|
|
}
|
|
|
|
public function exportReport($type)
|
|
{
|
|
Log::info('Reports::exportReport called - delegating to SingleReport', ['type' => $type]);
|
|
|
|
// Delegate to SingleReport for actual export functionality
|
|
$params = [
|
|
'fromDate' => request()->get('fromDate'),
|
|
'toDate' => request()->get('toDate'),
|
|
'decimal' => request()->get('decimal', 0),
|
|
];
|
|
|
|
$url = route('reports.pdf', $params);
|
|
$this->dispatch('openPdf', $url);
|
|
}
|
|
|
|
/**
|
|
* Export report as PDF with both chart images
|
|
*/
|
|
public function exportPdfWithCharts($returnRatioChartImage = null, $accountBalancesChartImage = null, $fromDate = null, $toDate = null)
|
|
{
|
|
abort_unless(Auth::check(), 403);
|
|
|
|
Log::info('Reports::exportPdfWithCharts called', [
|
|
'returnRatioChartImageLength' => $returnRatioChartImage ? strlen($returnRatioChartImage) : 0,
|
|
'accountBalancesChartImageLength' => $accountBalancesChartImage ? strlen($accountBalancesChartImage) : 0,
|
|
'fromDate' => $fromDate,
|
|
'toDate' => $toDate
|
|
]);
|
|
|
|
$chartImageIds = [];
|
|
|
|
// Process Return Ratio Chart image
|
|
if ($returnRatioChartImage) {
|
|
$returnRatioChartImageId = uniqid('return_ratio_chart_', true);
|
|
$tempImagePath = storage_path('app/temp/' . $returnRatioChartImageId . '.png');
|
|
|
|
// Ensure temp directory exists
|
|
if (!file_exists(dirname($tempImagePath))) {
|
|
mkdir(dirname($tempImagePath), 0755, true);
|
|
}
|
|
|
|
// Decode and validate image content before writing
|
|
$imageData = $this->decodeChartImage($returnRatioChartImage);
|
|
file_put_contents($tempImagePath, $imageData);
|
|
|
|
$chartImageIds['return_ratio_chart_id'] = $returnRatioChartImageId;
|
|
|
|
Log::info('Return Ratio Chart image saved to temp file', [
|
|
'chartImageId' => $returnRatioChartImageId,
|
|
'fileSize' => strlen($imageData)
|
|
]);
|
|
}
|
|
|
|
// Process Account Balances Chart image
|
|
if ($accountBalancesChartImage) {
|
|
$accountBalancesChartImageId = uniqid('account_balances_chart_', true);
|
|
$tempImagePath = storage_path('app/temp/' . $accountBalancesChartImageId . '.png');
|
|
|
|
// Ensure temp directory exists
|
|
if (!file_exists(dirname($tempImagePath))) {
|
|
mkdir(dirname($tempImagePath), 0755, true);
|
|
}
|
|
|
|
// Decode and validate image content before writing
|
|
$imageData = $this->decodeChartImage($accountBalancesChartImage);
|
|
file_put_contents($tempImagePath, $imageData);
|
|
|
|
$chartImageIds['account_balances_chart_id'] = $accountBalancesChartImageId;
|
|
|
|
Log::info('Account Balances Chart image saved to temp file', [
|
|
'chartImageId' => $accountBalancesChartImageId,
|
|
'fileSize' => strlen($imageData)
|
|
]);
|
|
}
|
|
|
|
// Store chart image IDs in session
|
|
session(['chart_image_ids' => $chartImageIds]);
|
|
|
|
// Build URL with current report parameters
|
|
$params = [
|
|
'fromDate' => $fromDate ?? request()->get('fromDate'),
|
|
'toDate' => $toDate ?? request()->get('toDate'),
|
|
'with_charts' => 1,
|
|
'decimal' => request()->get('decimal', 0),
|
|
];
|
|
|
|
$url = route('reports.pdf', $params);
|
|
Log::info('PDF URL generated with charts', ['url' => $url, 'chartImageIds' => $chartImageIds]);
|
|
|
|
// Use JavaScript to open PDF in new window/tab
|
|
$this->dispatch('openPdf', $url);
|
|
}
|
|
} |