Faza 8: PDF generation pentru fișa lucru (DomPDF)
- barryvdh/laravel-dompdf instalat - WorkOrderPdfService: încarcă WO cu toate relațiile (works/parts/payments), embed-ează logo ca data URI, foloseste theme_color din settings - Blade template /resources/views/pdf/work-order.blade.php: - Header cu logo + date companie + nr fișă + data - Box-uri client + auto (kilometraj/VIN/plate) - Plângere + diagnostic - Tabel manopere (h, preț/h, total) cu maistru pe fiecare rând - Tabel piese (cod, brand, qty, preț, total) - Box total cu discount + plăți efectuate + rest de achitat - Block recomandări cu fundal galben (warning) - Linii semnătură client + maistru - Footer cu timestamp generare - Action 'PDF' (icon descărcare) pe rând în lista de WO - Action 'Descarcă PDF' în header-ul paginii Edit WO
This commit is contained in:
@@ -134,6 +134,19 @@ class WorkOrderResource extends Resource
|
||||
->options(fn () => User::pluck('name', 'id')),
|
||||
])
|
||||
->actions([
|
||||
Actions\Action::make('pdf')
|
||||
->label('PDF')
|
||||
->icon('heroicon-m-document-arrow-down')
|
||||
->color('gray')
|
||||
->action(function (WorkOrder $r) {
|
||||
$svc = app(\App\Services\WorkOrderPdfService::class);
|
||||
$pdf = $svc->generate($r);
|
||||
$filename = $svc->filename($r);
|
||||
return response()->streamDownload(
|
||||
fn () => print($pdf->output()),
|
||||
$filename
|
||||
);
|
||||
}),
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
])
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Filament\Tenant\Resources\WorkOrderResource\Pages;
|
||||
|
||||
use App\Filament\Tenant\Resources\WorkOrderResource;
|
||||
use App\Models\Tenant\WorkOrder;
|
||||
use App\Services\WorkOrderPdfService;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
@@ -12,6 +14,22 @@ class EditWorkOrder extends EditRecord
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [Actions\DeleteAction::make()];
|
||||
return [
|
||||
Actions\Action::make('pdf')
|
||||
->label('Descarcă PDF')
|
||||
->icon('heroicon-m-document-arrow-down')
|
||||
->color('gray')
|
||||
->action(function () {
|
||||
/** @var WorkOrder $wo */
|
||||
$wo = $this->record;
|
||||
$svc = app(WorkOrderPdfService::class);
|
||||
$pdf = $svc->generate($wo);
|
||||
return response()->streamDownload(
|
||||
fn () => print($pdf->output()),
|
||||
$svc->filename($wo)
|
||||
);
|
||||
}),
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Tenant\WorkOrder;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
|
||||
class WorkOrderPdfService
|
||||
{
|
||||
public function generate(WorkOrder $wo): \Barryvdh\DomPDF\PDF
|
||||
{
|
||||
$wo->load(['client', 'vehicle', 'master', 'works.master', 'parts', 'payments']);
|
||||
$company = $wo->company ?: \App\Models\Central\Company::find($wo->company_id);
|
||||
|
||||
$themeColor = $company?->settings['theme_color'] ?? '#3B82F6';
|
||||
$currency = $company?->settings['currency'] ?? 'MDL';
|
||||
$worksTotal = (float) $wo->works->sum('total');
|
||||
$partsTotal = (float) $wo->parts->sum('total');
|
||||
$paid = (float) $wo->payments->sum('amount');
|
||||
$balance = max(0, (float) $wo->total - $paid);
|
||||
|
||||
// Embed logo as data URI (DomPDF can't fetch external URLs reliably).
|
||||
$logoData = null;
|
||||
if ($company && ($logoMedia = $company->getFirstMedia('logo'))) {
|
||||
try {
|
||||
$path = $logoMedia->getPath();
|
||||
if (file_exists($path)) {
|
||||
$mime = mime_content_type($path) ?: 'image/png';
|
||||
$logoData = 'data:' . $mime . ';base64,' . base64_encode(file_get_contents($path));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$logoData = null;
|
||||
}
|
||||
}
|
||||
|
||||
return Pdf::loadView('pdf.work-order', [
|
||||
'wo' => $wo,
|
||||
'company' => $company,
|
||||
'themeColor' => $themeColor,
|
||||
'currency' => $currency,
|
||||
'worksTotal' => $worksTotal,
|
||||
'partsTotal' => $partsTotal,
|
||||
'paid' => $paid,
|
||||
'balance' => $balance,
|
||||
'logoData' => $logoData,
|
||||
])->setPaper('A4');
|
||||
}
|
||||
|
||||
public function filename(WorkOrder $wo): string
|
||||
{
|
||||
return 'WO-' . $wo->number . '-' . optional($wo->opened_at)->format('Ymd') . '.pdf';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user