171 lines
6.0 KiB
PHP
171 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace Modules\AssetExchange\Http\Controllers;
|
|
|
|
use App\Contact;
|
|
use App\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\AssetExchange\Http\Controllers\Concerns\AuthorizesAssetExchange;
|
|
use Modules\AssetExchange\Models\Listing;
|
|
use Modules\AssetExchange\Models\PriceInquiry;
|
|
use Modules\AssetExchange\Models\PriceInquiryRecipient;
|
|
use Modules\AssetExchange\Services\InquirySlaService;
|
|
use Modules\AssetExchange\Services\PriceInquiryService;
|
|
use Modules\AssetExchange\Utils\AssetExchangeUtil;
|
|
|
|
class PriceInquiryController extends Controller
|
|
{
|
|
use AuthorizesAssetExchange;
|
|
|
|
public function __construct(
|
|
protected AssetExchangeUtil $aexUtil,
|
|
protected PriceInquiryService $inquiryService,
|
|
protected InquirySlaService $slaService
|
|
) {
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.view');
|
|
|
|
$business = $this->aexUtil->getBusiness();
|
|
$business_id = $business->id;
|
|
$query = PriceInquiry::where('business_id', $business_id)
|
|
->with(['listing', 'recipients'])
|
|
->orderByDesc('created_at');
|
|
|
|
if ($status = $request->get('status')) {
|
|
$query->where('status', $status);
|
|
}
|
|
|
|
$filter = $request->get('filter');
|
|
if ($filter === 'urgent') {
|
|
$this->slaService->applyUrgentFilter($query, 'urgent', $business_id);
|
|
}
|
|
|
|
$inquiries = $query->paginate(25)->appends($request->only(['status', 'filter']));
|
|
|
|
$sla = $this->slaService->slaSettings($business_id);
|
|
$slaMap = [];
|
|
foreach ($inquiries as $inq) {
|
|
$slaMap[$inq->id] = $this->slaService->inquirySlaStatus($inq, $sla);
|
|
}
|
|
|
|
$slaSnapshot = $this->slaService->snapshot($business);
|
|
|
|
return view('assetexchange::inquiries.index', [
|
|
'inquiries' => $inquiries,
|
|
'statuses' => $this->aexUtil->statusLabels(),
|
|
'sla' => $sla,
|
|
'slaMap' => $slaMap,
|
|
'slaSnapshot' => $slaSnapshot,
|
|
'activeFilter' => $filter,
|
|
'activeStatus' => $request->get('status'),
|
|
]);
|
|
}
|
|
|
|
public function create(Request $request)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.create');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$listing = null;
|
|
if ($request->filled('listing_id')) {
|
|
$listing = Listing::where('business_id', $business_id)->findOrFail($request->listing_id);
|
|
}
|
|
|
|
return view('assetexchange::inquiries.create', [
|
|
'listing' => $listing,
|
|
'listings' => Listing::where('business_id', $business_id)->orderByDesc('id')->limit(200)->pluck('title', 'id'),
|
|
'suppliers' => Contact::suppliersDropdown($business_id, false, true),
|
|
'users' => User::forDropdown($business_id, false, false, true),
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.create');
|
|
|
|
$business = $this->aexUtil->getBusiness();
|
|
$listing = Listing::where('business_id', $business->id)->findOrFail($request->listing_id);
|
|
|
|
$data = $request->validate([
|
|
'listing_id' => 'required|exists:aex_listings,id',
|
|
'appraisal_id' => 'nullable|integer',
|
|
'title' => 'nullable|string|max:255',
|
|
'inquiry_type' => 'nullable|in:supplier_rfq,internal_research,mixed',
|
|
'notes' => 'nullable|string',
|
|
'due_date' => 'nullable|string',
|
|
'from_appraisal' => 'sometimes|boolean',
|
|
'supplier_contact_ids' => 'nullable|array',
|
|
'supplier_contact_ids.*' => 'integer',
|
|
'internal_user_ids' => 'nullable|array',
|
|
'internal_user_ids.*' => 'integer',
|
|
]);
|
|
|
|
$data['from_appraisal'] = $request->boolean('from_appraisal');
|
|
|
|
try {
|
|
$inquiry = $this->inquiryService->create($business, $listing, $data, auth()->user());
|
|
} catch (\Throwable $e) {
|
|
return redirect()->back()->with('status', $e->getMessage());
|
|
}
|
|
|
|
return redirect()
|
|
->action([self::class, 'show'], [$inquiry->id])
|
|
->with('status', __('assetexchange::lang.inquiry_created'));
|
|
}
|
|
|
|
public function show($id)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.view');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$inquiry = PriceInquiry::where('business_id', $business_id)
|
|
->with(['listing', 'lines', 'recipients.contact', 'recipients.user'])
|
|
->findOrFail($id);
|
|
|
|
$sla = $this->slaService->slaSettings($business_id);
|
|
$slaStatus = $this->slaService->inquirySlaStatus($inquiry, $sla);
|
|
|
|
return view('assetexchange::inquiries.show', [
|
|
'inquiry' => $inquiry,
|
|
'sla' => $sla,
|
|
'slaStatus' => $slaStatus,
|
|
'suppliers' => Contact::suppliersDropdown($business_id, false, true),
|
|
'users' => User::forDropdown($business_id, false, false, true),
|
|
]);
|
|
}
|
|
|
|
public function send($id)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.manage');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$inquiry = PriceInquiry::where('business_id', $business_id)->findOrFail($id);
|
|
|
|
$this->inquiryService->send($inquiry, auth()->user());
|
|
|
|
return redirect()->back()->with('status', __('assetexchange::lang.inquiry_sent'));
|
|
}
|
|
|
|
public function recordQuote(Request $request, $recipientId)
|
|
{
|
|
$this->authorizeAexAccess('aex.inquiries.manage');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$recipient = PriceInquiryRecipient::where('business_id', $business_id)->findOrFail($recipientId);
|
|
|
|
$data = $request->validate([
|
|
'quoted_price' => 'required|integer|min:0',
|
|
'currency' => 'nullable|string|max:10',
|
|
'quote_notes' => 'nullable|string',
|
|
]);
|
|
|
|
$this->inquiryService->recordQuote($recipient, $data, auth()->user());
|
|
|
|
return redirect()->back()->with('status', __('assetexchange::lang.quote_recorded'));
|
|
}
|
|
}
|