118 lines
4.7 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;
use App\Services\RfqInvitationService;
use Illuminate\Http\Request;
class RfqController extends Controller
{
public function show(PurchaseRequest $purchaseRequest)
{
$suppliers = Supplier::where('is_active', true)->orderBy('name')->get();
$invitations = $purchaseRequest->rfqInvitations()->with('supplier', 'quote')->get();
return view('purchase.rfq.show', ['request' => $purchaseRequest, 'suppliers' => $suppliers, 'invitations' => $invitations]);
}
public function selectSuppliers(Request $request, PurchaseRequest $purchaseRequest, RfqInvitationService $service, PurchaseStageService $stages)
{
$mode = $request->input('mode', 'global');
$alreadySelected = $purchaseRequest->rfqInvitations()->pluck('supplier_id')->toArray();
$added = 0;
if ($mode === 'by_item') {
// item_suppliers[item_id][] = supplier_id → invert to supplier_id → [item_ids]
$itemSuppliers = $request->input('item_suppliers', []);
$supplierItems = [];
foreach ($itemSuppliers as $itemId => $supplierIds) {
foreach ((array) $supplierIds as $supplierId) {
$supplierItems[$supplierId][] = (int) $itemId;
}
}
if (empty($supplierItems)) {
return redirect()->back()->with('error', 'Please assign at least one supplier to an item.');
}
foreach ($supplierItems as $supplierId => $itemIds) {
if (in_array($supplierId, $alreadySelected)) {
continue;
}
$channel = $request->input('channel_' . $supplierId, 'email');
$supplier = Supplier::findOrFail($supplierId);
$service->select($purchaseRequest, $supplier, $channel, $itemIds);
$added++;
}
} else {
$validated = $request->validate([
'supplier_ids' => ['required', 'array', 'min:1'],
'supplier_ids.*' => ['required', 'exists:suppliers,id'],
]);
foreach ($validated['supplier_ids'] as $supplierId) {
if (in_array($supplierId, $alreadySelected)) {
continue;
}
$channel = $request->input('channel_' . $supplierId, 'email');
$supplier = Supplier::findOrFail($supplierId);
$service->select($purchaseRequest, $supplier, $channel);
$added++;
}
}
$stages->setStage($purchaseRequest, 'rfq');
return redirect()->route('purchase.pipeline.show', $purchaseRequest)
->with('success', $added . ' supplier(s) added. Now send them the quote request links.');
}
public function sendAll(PurchaseRequest $purchaseRequest, RfqInvitationService $service, PurchaseStageService $stages)
{
$pending = $purchaseRequest->rfqInvitations()->where('status', 'pending')->with('supplier')->get();
if ($pending->isEmpty()) {
return redirect()->back()->with('error', 'No unsent invitations. Select suppliers first.');
}
foreach ($pending as $invitation) {
$service->sendInvitation($invitation);
}
$stages->setStage($purchaseRequest, 'quoting');
return redirect()->route('purchase.pipeline.show', $purchaseRequest)
->with('success', $pending->count() . ' supplier(s) notified. Waiting for quotes.');
}
public function store(Request $request, PurchaseRequest $purchaseRequest, RfqInvitationService $service, PurchaseStageService $stages)
{
$validated = $request->validate([
'supplier_ids' => ['required', 'array', 'min:1'],
'supplier_ids.*' => ['required', 'exists:suppliers,id'],
]);
$alreadyInvited = $purchaseRequest->rfqInvitations()->pluck('supplier_id')->toArray();
$sent = 0;
foreach ($validated['supplier_ids'] as $supplierId) {
if (in_array($supplierId, $alreadyInvited)) {
continue;
}
$channel = $request->input('channel_' . $supplierId, 'both');
$supplier = Supplier::findOrFail($supplierId);
$service->invite($purchaseRequest, $supplier, $channel);
$sent++;
}
$stages->setStage($purchaseRequest, 'quoting');
return redirect()->route('purchase.requests.rfq', $purchaseRequest)
->with('success', $sent . ' invitation(s) sent. Waiting for supplier quotes.');
}
}