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:
2026-05-07 13:01:42 +00:00
parent f1d196f018
commit 19a7afac27
6 changed files with 904 additions and 2 deletions
+53
View File
@@ -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';
}
}