invoice = $invoice->load([ 'customer', 'branch', 'createdBy', 'serviceOrder.vehicle', 'jobCard.vehicle', 'estimate', 'lineItems.part', 'lineItems.serviceItem', ]); } public function downloadPDF() { try { // Generate HTML from the template $html = view('invoices.pdf', ['invoice' => $this->invoice])->render(); if (empty($html)) { throw new \Exception('Failed to generate PDF template'); } // Try different approaches for PDF generation try { // Approach 1: Use Laravel's PDF facade if available if (class_exists('\Barryvdh\DomPDF\Facade\Pdf')) { $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadHtml($html); $pdf->setPaper('letter', 'portrait'); $output = $pdf->output(); } else { throw new \Exception('PDF facade not available'); } } catch (\Exception $e1) { try { // Approach 2: Direct DomPDF instantiation $dompdf = new \Dompdf\Dompdf; $dompdf->loadHtml($html); $dompdf->setPaper('letter', 'portrait'); $dompdf->render(); $output = $dompdf->output(); } catch (\Exception $e2) { // Approach 3: Return HTML for now $filename = 'invoice-'.$this->invoice->invoice_number.'.html'; return response()->streamDownload(function () use ($html) { echo $html; }, $filename, [ 'Content-Type' => 'text/html', 'Content-Disposition' => 'attachment; filename="'.$filename.'"', ]); } } // Create filename with invoice number $filename = 'invoice-'.$this->invoice->invoice_number.'.pdf'; // Return PDF for download return response()->streamDownload(function () use ($output) { echo $output; }, $filename, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'attachment; filename="'.$filename.'"', ]); } catch (\Exception $e) { // Log the error for debugging Log::error('PDF generation failed for invoice '.$this->invoice->id, [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); // Show user-friendly error message session()->flash('error', 'Failed to generate PDF: '.$e->getMessage()); return null; } } public function markAsPaid() { if (! auth()->user()->can('update', $this->invoice)) { session()->flash('error', 'You do not have permission to update this invoice.'); return; } $this->invoice->markAsPaid('manual', null, 'Marked as paid from invoice view'); $this->invoice->refresh(); session()->flash('success', 'Invoice marked as paid successfully.'); } public function sendInvoice() { if (! auth()->user()->can('update', $this->invoice)) { session()->flash('error', 'You do not have permission to send this invoice.'); return; } // This would typically integrate with email service $this->invoice->markAsSent('email', $this->invoice->customer->email); $this->invoice->refresh(); session()->flash('success', 'Invoice sent successfully.'); } public function duplicateInvoice() { if (! auth()->user()->can('create', Invoice::class)) { session()->flash('error', 'You do not have permission to create invoices.'); return; } try { $newInvoice = $this->invoice->replicate(); $newInvoice->invoice_number = Invoice::generateInvoiceNumber($this->invoice->branch->code); $newInvoice->status = 'draft'; $newInvoice->invoice_date = now()->toDateString(); $newInvoice->due_date = now()->addDays(30)->toDateString(); $newInvoice->paid_at = null; $newInvoice->payment_method = null; $newInvoice->payment_reference = null; $newInvoice->payment_notes = null; $newInvoice->sent_at = null; $newInvoice->sent_method = null; $newInvoice->sent_to = null; $newInvoice->created_by = auth()->id(); $newInvoice->save(); // Duplicate line items foreach ($this->invoice->lineItems as $lineItem) { $newLineItem = $lineItem->replicate(); $newLineItem->invoice_id = $newInvoice->id; $newLineItem->save(); } // Recalculate totals $newInvoice->recalculateTotals(); return redirect()->route('invoices.edit', $newInvoice); } catch (\Exception $e) { Log::error('Failed to duplicate invoice', [ 'invoice_id' => $this->invoice->id, 'error' => $e->getMessage(), ]); session()->flash('error', 'Failed to duplicate invoice. Please try again.'); } } #[Layout('components.layouts.app.sidebar')] public function render() { return view('livewire.invoices.show'); } }