- Pipeline page: clicking a supplier quote card opens a modal with full
line-item breakdown, lead time, payment terms, notes, awarded status,
and a Compare All Quotes button
- Eager-load supplierQuotes.supplier and supplierQuotes.items in pipeline
controller to avoid N+1 on the modal data
- Browser tab now shows SteelERP first (SteelERP — Page Name)
- Added SVG favicon matching the sidebar blue-square logo
- Notification clicks now navigate to the relevant page via a dedicated
/notifications/{id}/go route that marks only that notification as read
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
52 lines
1.5 KiB
PHP
52 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Purchase;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\PurchaseRequest;
|
|
use App\Models\Supplier;
|
|
use App\Services\PurchaseStageService;
|
|
|
|
class PurchasePipelineController extends Controller
|
|
{
|
|
private function withRelations()
|
|
{
|
|
return PurchaseRequest::with([
|
|
'requestedBy',
|
|
'signature.signedBy',
|
|
'rfqInvitations.supplier',
|
|
'supplierQuotes',
|
|
'awardedQuote.supplier',
|
|
]);
|
|
}
|
|
|
|
public function index(PurchaseStageService $stages)
|
|
{
|
|
$active = $this->withRelations()->where('stage', '!=', 'complete')->latest()->get();
|
|
$completed = $this->withRelations()->where('stage', 'complete')->latest()->get();
|
|
|
|
return view('purchase.pipeline.index', compact('active', 'completed', 'stages'));
|
|
}
|
|
|
|
public function show(PurchaseRequest $purchaseRequest, PurchaseStageService $stages)
|
|
{
|
|
$purchaseRequest->load([
|
|
'requestedBy',
|
|
'items',
|
|
'signature.signedBy',
|
|
'rfqInvitations.supplier',
|
|
'supplierQuotes.supplier',
|
|
'supplierQuotes.items',
|
|
'awardedQuote.supplier',
|
|
]);
|
|
|
|
$suppliers = Supplier::where('is_active', true)->orderBy('name')->get();
|
|
|
|
return view('purchase.pipeline.show', [
|
|
'pr' => $purchaseRequest,
|
|
'stages' => $stages,
|
|
'suppliers' => $suppliers,
|
|
]);
|
|
}
|
|
}
|