sackey e3b2b220d2
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Enhance UI and functionality across various components
- Increased icon sizes in service items, service orders, users, and technician management for better visibility.
- Added custom loading indicators with appropriate icons in search fields for vehicles, work orders, and technicians.
- Introduced invoice management routes for better organization and access control.
- Created a new test for the estimate PDF functionality to ensure proper rendering and data integrity.
2025-08-16 14:36:58 +00:00

172 lines
5.8 KiB
PHP

<?php
namespace App\Livewire\Invoices;
use App\Models\Invoice;
use Illuminate\Support\Facades\Log;
use Livewire\Attributes\Layout;
use Livewire\Component;
class Show extends Component
{
public Invoice $invoice;
public function mount(Invoice $invoice)
{
$this->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');
}
}