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

179 lines
5.2 KiB
PHP

<?php
namespace App\Livewire\Invoices;
use App\Models\Branch;
use App\Models\Invoice;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;
class Index extends Component
{
use WithPagination;
public $search = '';
public $filterStatus = '';
public $filterBranch = '';
public $filterDateFrom = '';
public $filterDateTo = '';
public $sortField = 'invoice_date';
public $sortDirection = 'desc';
protected $queryString = [
'search' => ['except' => ''],
'filterStatus' => ['except' => ''],
'filterBranch' => ['except' => ''],
'sortField' => ['except' => 'invoice_date'],
'sortDirection' => ['except' => 'desc'],
];
public function mount()
{
// Set default date filter to current month
$this->filterDateFrom = now()->startOfMonth()->format('Y-m-d');
$this->filterDateTo = now()->endOfMonth()->format('Y-m-d');
}
public function updatingSearch()
{
$this->resetPage();
}
public function updatingFilterStatus()
{
$this->resetPage();
}
public function updatingFilterBranch()
{
$this->resetPage();
}
public function sortBy($field)
{
if ($this->sortField === $field) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
} else {
$this->sortField = $field;
$this->sortDirection = 'asc';
}
$this->resetPage();
}
public function clearFilters()
{
$this->reset(['search', 'filterStatus', 'filterBranch', 'filterDateFrom', 'filterDateTo']);
$this->resetPage();
}
public function deleteInvoice($invoiceId)
{
$invoice = Invoice::findOrFail($invoiceId);
// Check permissions
if (! auth()->user()->can('delete', $invoice)) {
session()->flash('error', 'You do not have permission to delete this invoice.');
return;
}
// Only allow deletion of draft invoices
if ($invoice->status !== 'draft') {
session()->flash('error', 'Only draft invoices can be deleted.');
return;
}
$invoice->delete();
session()->flash('success', 'Invoice deleted successfully.');
}
public function markAsPaid($invoiceId)
{
$invoice = Invoice::findOrFail($invoiceId);
if (! auth()->user()->can('update', $invoice)) {
session()->flash('error', 'You do not have permission to update this invoice.');
return;
}
$invoice->markAsPaid('manual', null, 'Marked as paid from invoice list');
session()->flash('success', 'Invoice marked as paid.');
}
public function sendInvoice($invoiceId)
{
$invoice = Invoice::findOrFail($invoiceId);
if (! auth()->user()->can('update', $invoice)) {
session()->flash('error', 'You do not have permission to send this invoice.');
return;
}
// This would typically integrate with email service
$invoice->markAsSent('email', $invoice->customer->email);
session()->flash('success', 'Invoice sent successfully.');
}
public function getInvoicesProperty()
{
return Invoice::query()
->with(['customer', 'branch', 'createdBy'])
->when($this->search, function (Builder $query) {
$query->where(function ($q) {
$q->where('invoice_number', 'like', '%'.$this->search.'%')
->orWhereHas('customer', function ($customerQuery) {
$customerQuery->where('first_name', 'like', '%'.$this->search.'%')
->orWhere('last_name', 'like', '%'.$this->search.'%')
->orWhere('email', 'like', '%'.$this->search.'%')
->orWhereRaw("CONCAT(first_name, ' ', last_name) LIKE ?", ['%'.$this->search.'%']);
});
});
})
->when($this->filterStatus, function (Builder $query) {
$query->where('status', $this->filterStatus);
})
->when($this->filterBranch, function (Builder $query) {
$query->where('branch_id', $this->filterBranch);
})
->when($this->filterDateFrom, function (Builder $query) {
$query->where('invoice_date', '>=', $this->filterDateFrom);
})
->when($this->filterDateTo, function (Builder $query) {
$query->where('invoice_date', '<=', $this->filterDateTo);
})
->orderBy($this->sortField, $this->sortDirection)
->paginate(15);
}
public function getBranchesProperty()
{
return Branch::orderBy('name')->get();
}
public function getStatusOptionsProperty()
{
return Invoice::getStatusOptions();
}
#[Layout('components.layouts.app.sidebar')]
public function render()
{
return view('livewire.invoices.index', [
'invoices' => $this->invoices,
'branches' => $this->branches,
'statusOptions' => $this->statusOptions,
]);
}
}