Initial commit
This commit is contained in:
199
app/Http/Livewire/Reports.php
Normal file
199
app/Http/Livewire/Reports.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user