feat(offers): complete phase five operational controls in QA

This commit is contained in:
2026-11-14 18:08:46 +02:00
parent e431de8b42
commit 528a2597ed
33 changed files with 2383 additions and 19 deletions
@@ -3,12 +3,14 @@
namespace App\Http\Controllers;
use App\Models\Opportunity;
use App\Services\OfferAvailability;
use App\Services\OpportunityCanonicalContract;
use App\Services\OpportunityManagement;
use App\Services\OpportunityProfileWorkflow;
use App\Services\OpportunityResources;
use App\Services\PortalProfileAccess;
use App\Services\PrivateOfferConfidentiality;
use App\Services\PrivateOfferOperations;
use App\Services\PrivateOfferPreparation;
use App\Services\VerifiedDocumentBinary;
use Illuminate\Http\JsonResponse;
@@ -86,14 +88,20 @@ final class PrivateOfferPreparationController extends Controller
public function index(Request $request, PortalProfileAccess $access): Response
{
$filters = $request->validate(['state' => 'nullable|in:draft,submitted,in_review,needs_information,rejected,approved']);
$records = $access->scope(Opportunity::query(), $request->user())->whereNotNull('workflow_context->private_offer_preparation')
$filters = $request->validate(['state' => 'nullable|in:draft,submitted,in_review,needs_information,rejected,approved', 'operational' => 'nullable|boolean', 'pending_reports' => 'nullable|boolean']);
$query = ($filters['operational'] ?? false) ? app(PrivateOfferOperations::class)->staffQuery($request->user()) : $access->scope(Opportunity::query(), $request->user());
if ($filters['pending_reports'] ?? false) {
$query = app(PrivateOfferOperations::class)->staffQuery($request->user());
$query->whereRaw("jsonb_path_exists(COALESCE(workflow_context->'offer_reports','{}'::jsonb), '$.* ? (@.status == \"open\" || @.status == \"in_review\")')");
}
$records = $query->whereNotNull('workflow_context->private_offer_preparation')
->when($filters['state'] ?? null, fn ($q, $state) => $q->where('workflow_context->private_offer_preparation->state', $state))
->orderByDesc('id')->paginate(20)->withQueryString();
return Inertia::render('offers/preparation-index', ['records' => $records->through(fn ($r) => [
'id' => $r->id, 'title' => app(OpportunityManagement::class)->values($r)['title'] ?? null, 'reference' => $r->reference,
'state' => $access->state($r),
'availability' => app(OfferAvailability::class)->record($r)['state'],
]), 'filters' => $filters, 'canCreate' => count($access->navigation($request->user())['contexts']) > 0]);
}