['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, ]); } }