ultimatepos/Modules/IntegrationHub/Http/Controllers/ExportController.php

136 lines
5.2 KiB
PHP

<?php
namespace Modules\IntegrationHub\Http\Controllers;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Modules\IntegrationHub\Events\IntegrationExportCompleted;
use Modules\IntegrationHub\Models\IhExportJob;
use Modules\IntegrationHub\Services\ExecutiveCockpitExportService;
use Modules\IntegrationHub\Services\ODataExportService;
use Modules\IntegrationHub\Services\WebhookDispatcherService;
class ExportController extends Controller
{
public function index(Request $request)
{
if (! auth()->user()->can('integrationhub.export')) {
abort(403);
}
$business_id = (int) $request->session()->get('user.business_id');
$jobs = IhExportJob::forBusiness($business_id)->latest('id')->paginate(20);
$datasets = config('integrationhub.datasets', []);
$formats = config('integrationhub.export_formats', ['json']);
return view('integrationhub::exports.index', compact('jobs', 'datasets', 'formats'));
}
public function store(Request $request, ODataExportService $odataService, WebhookDispatcherService $webhooks)
{
if (! auth()->user()->can('integrationhub.export')) {
abort(403);
}
$validated = $request->validate([
'dataset' => 'required|string',
'format' => 'required|in:json,csv,xlsx',
'start_date' => 'nullable|date',
'end_date' => 'nullable|date',
]);
$business_id = (int) $request->session()->get('user.business_id');
$dataset = $validated['dataset'];
$format = $validated['format'];
if (! in_array($dataset, config('integrationhub.datasets', []), true)) {
return back()->with('status', ['success' => 0, 'msg' => __('integrationhub::lang.invalid_dataset')]);
}
$job = IhExportJob::create([
'business_id' => $business_id,
'dataset' => $dataset,
'format' => $format,
'status' => 'processing',
]);
try {
if ($dataset === 'executive_cockpit') {
$cockpitExport = app(ExecutiveCockpitExportService::class);
$start = ! empty($validated['start_date']) ? Carbon::parse($validated['start_date']) : now()->startOfMonth();
$end = ! empty($validated['end_date']) ? Carbon::parse($validated['end_date']) : now();
$job = $cockpitExport->export($business_id, $format, $start, $end);
} else {
$filters = array_filter([
'start_date' => $validated['start_date'] ?? null,
'end_date' => $validated['end_date'] ?? null,
]);
$payload = $odataService->dataset($business_id, $dataset, $filters);
$path = $this->storePayload($business_id, $job->id, $dataset, $format, $payload);
$job->markCompleted($path);
IntegrationExportCompleted::dispatch($business_id, $dataset, $format, $path, $job->id);
$webhooks->dispatch($business_id, 'export.completed', [
'export_job_id' => $job->id,
'dataset' => $dataset,
'format' => $format,
'file_path' => $path,
]);
}
return redirect()
->action([self::class, 'index'])
->with('status', ['success' => 1, 'msg' => __('integrationhub::lang.export_queued')]);
} catch (\Throwable $e) {
$job->markFailed();
return back()->with('status', ['success' => 0, 'msg' => $e->getMessage()]);
}
}
public function download(Request $request, $id)
{
if (! auth()->user()->can('integrationhub.export')) {
abort(403);
}
$business_id = (int) $request->session()->get('user.business_id');
$job = IhExportJob::forBusiness($business_id)->findOrFail($id);
if ($job->status !== 'completed' || empty($job->file_path) || ! Storage::disk('local')->exists($job->file_path)) {
abort(404);
}
return Storage::disk('local')->download($job->file_path);
}
protected function storePayload(int $businessId, int $jobId, string $dataset, string $format, array $payload): string
{
$directory = "integrationhub/exports/{$businessId}";
$filename = "{$dataset}_{$jobId}_".now()->format('Ymd_His');
$path = "{$directory}/{$filename}.json";
if ($format === 'csv' && isset($payload['value'])) {
$path = "{$directory}/{$filename}.csv";
$handle = fopen('php://temp', 'r+');
$rows = $payload['value'];
if (! empty($rows)) {
fputcsv($handle, array_keys((array) $rows[0]));
foreach ($rows as $row) {
fputcsv($handle, (array) $row);
}
}
rewind($handle);
Storage::disk('local')->put($path, stream_get_contents($handle));
fclose($handle);
return $path;
}
Storage::disk('local')->put($path, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
return $path;
}
}