Certainly! Below is a step-by-step, production-ready solution for your requirements using Eloquent, Livewire, and with support for search and pagination.
1. Eloquent Query for Paginated, Searchable Data
Create a Livewire component (e.g. TakenInventoryInfoIndex). Here’s how you can load, filter, and paginate the data:
Livewire Component: TakenInventoryInfoIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\TakenInventoryInfo;
use Illuminate\Support\Facades\Auth;
class TakenInventoryInfoIndex extends Component
{
use WithPagination;
public $search = '';
public $storeTo = null;
public $perPage = 10;
public function updatingSearch()
{
$this->resetPage();
}
public function render()
{
// Get user's store ids
$userStoreIds = Auth::user()->stores->pluck('id');
$query = TakenInventoryInfo::with([
'store', // store_from
'takenInventories.store' // eager load store_to via takenInventories
])
->whereIn('store_id', $userStoreIds);
// Search by tracking_no or taken_date
if ($this->search) {
$query->where(function($q) {
$q->where('tracking_no', 'LIKE', '%'.$this->search.'%')
->orWhere('taken_date', 'LIKE', '%'.$this->search.'%');
});
}
// Filter by store_to if provided
if ($this->storeTo) {
// Filter if any of related takenInventories is for the target store
$query->whereHas('takenInventories', function($q) {
$q->where('store_id', $this->storeTo);
});
}
$takenInventoryInfos = $query->orderBy('taken_date', 'desc')
->paginate($this->perPage);
return view('livewire.taken-inventory-info-index', [
'infos' => $takenInventoryInfos
]);
}
}
2. Your Livewire Blade View
<!-- resources/views/livewire/taken-inventory-info-index.blade.php -->
<div>
<input type="text" wire:model.debounce.500ms="search" placeholder="Search by Tracking No. or Date...">
<select wire:model="storeTo">
<option value="">All Store To</option>
@foreach(\App\Models\Store::all() as $store)
<option value="{{ $store->id }}">{{ $store->name }}</option>
@endforeach
</select>
<table>
<thead>
<tr>
<th>Tracking No</th>
<th>Store From</th>
<th>Store To</th>
<th>Taken Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($infos as $info)
<tr>
<td>{{ $info->tracking_no }}</td>
<td>{{ $info->store->name ?? '-' }}</td>
<td>
@foreach($info->takenInventories as $taken)
{{ $taken->store->name ?? '-' }} @if ( !$loop->last ), @endif
@endforeach
</td>
<td>{{ $info->taken_date }}</td>
<td>
<a href="{{ route('taken-inventory.info.show', $info->id) }}">View</a>
<a href="{{ route('taken-inventory.info.print', $info->id) }}" target="_blank">Print PDF</a>
</td>
</tr>
@endforeach
</tbody>
</table>
{{ $infos->links() }}
</div>
3. Controller for PDF Export
public function print($id)
{
$info = TakenInventoryInfo::with(['store', 'takenInventories.store'])->findOrFail($id);
$pdf = \PDF::loadView('pdf.taken-inventory-info', compact('info'));
return $pdf->download("taken-inventory-info-$id.pdf");
}
4. Example of PDF Blade View (resources/views/pdf/taken-inventory-info.blade.php)
<h1>Taken Inventory Info: {{ $info->tracking_no }}</h1>
<p>Store From: {{ $info->store->name ?? '-' }}</p>
<p>Taken Date: {{ $info->taken_date }}</p>
<h2>Taken Inventories</h2>
<ul>
@foreach($info->takenInventories as $taken)
<li>
Store To: {{ $taken->store->name ?? '-' }},
Quantity: {{ $taken->quantity }}
</li>
@endforeach
</ul>
5. Routes Example (routes/web.php)
Route::get('taken-inventory-info/{id}/show', ...)->name('taken-inventory.info.show');
Route::get('taken-inventory-info/{id}/print', [YourController::class, 'print'])->name('taken-inventory.info.print');
6. Notes
- This setup is searchable, filterable by store_to, and paginated.
- The PDF generation uses barryvdh/laravel-dompdf.
- Adjust as needed for authorization, policies, or more complex filtering.
- For view all TakenInventories of TakenInventoryInfo, link to a detail/show page.
Let me know if you need further details or a sample controller for the CRUD/show endpoint!