feat(offers): complete phase five operational controls in QA
This commit is contained in:
@@ -8,7 +8,7 @@ use App\Services\OpportunityManagement;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
final class OfferPublicCatalogueController extends Controller
|
||||
@@ -17,30 +17,30 @@ final class OfferPublicCatalogueController extends Controller
|
||||
{
|
||||
$filters = $catalogue->filters($request);
|
||||
|
||||
return Inertia::render('offers/catalogue', [...$catalogue->page($request, $filters), 'filters' => $filters,
|
||||
return $this->uncached(Inertia::render('offers/catalogue', [...$catalogue->page($request, $filters), 'filters' => $filters,
|
||||
'mapData' => in_array($filters['view'] ?? '', ['map', 'combined'], true) ? $catalogue->map($filters) : null,
|
||||
'territorySelection' => app(InvestmentGeography::class)->selection($filters),
|
||||
'references' => ['categories' => OpportunityManagement::CATEGORIES, 'options' => [], 'clusters' => [], 'corridors' => [], 'projects' => [], 'locations' => [], 'sectors' => []]]);
|
||||
'references' => ['categories' => OpportunityManagement::CATEGORIES, 'options' => [], 'clusters' => [], 'corridors' => [], 'projects' => [], 'locations' => [], 'sectors' => []]])->toResponse($request));
|
||||
}
|
||||
|
||||
public function show(int $id, OfferPublicCatalogue $catalogue): Response
|
||||
public function show(Request $request, int $id, OfferPublicCatalogue $catalogue): Response
|
||||
{
|
||||
return Inertia::render('offers/public-detail', ['offer' => $catalogue->detail($id)]);
|
||||
return $this->uncached(Inertia::render('offers/public-detail', ['offer' => $catalogue->detail($id)])->toResponse($request));
|
||||
}
|
||||
|
||||
public function search(Request $request, OfferPublicCatalogue $catalogue): JsonResponse
|
||||
{
|
||||
return response()->json($catalogue->page($request, $catalogue->filters($request)));
|
||||
return response()->json($catalogue->page($request, $catalogue->filters($request)))->header('Cache-Control', 'private, no-store');
|
||||
}
|
||||
|
||||
public function detail(int $id, OfferPublicCatalogue $catalogue): JsonResponse
|
||||
{
|
||||
return response()->json(['data' => $catalogue->detail($id)]);
|
||||
return response()->json(['data' => $catalogue->detail($id)])->header('Cache-Control', 'private, no-store');
|
||||
}
|
||||
|
||||
public function map(Request $request, OfferPublicCatalogue $catalogue): JsonResponse
|
||||
{
|
||||
return response()->json($catalogue->map($catalogue->filters($request)));
|
||||
return response()->json($catalogue->map($catalogue->filters($request)))->header('Cache-Control', 'private, no-store');
|
||||
}
|
||||
|
||||
public function export(Request $request, OfferPublicCatalogue $catalogue): StreamedResponse
|
||||
@@ -60,6 +60,13 @@ final class OfferPublicCatalogueController extends Controller
|
||||
fputcsv($stream, array_map(fn ($value) => preg_match('/^[\s]*[=+@-]/u', (string) $value) ? "'".$value : $value, $fields), ';', '"', '');
|
||||
}
|
||||
fclose($stream);
|
||||
}, 'ofertas.csv', ['Content-Type' => 'text/csv; charset=UTF-8', 'X-Export-Limit' => '1000', 'X-Results-Truncated' => $result['truncated'] ? 'true' : 'false']);
|
||||
}, 'ofertas.csv', ['Content-Type' => 'text/csv; charset=UTF-8', 'Cache-Control' => 'private, no-store', 'X-Export-Limit' => '1000', 'X-Results-Truncated' => $result['truncated'] ? 'true' : 'false']);
|
||||
}
|
||||
|
||||
private function uncached(Response $response): Response
|
||||
{
|
||||
$response->headers->set('Cache-Control', 'private, no-store');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ final class PortalEditorialWorkflowController extends Controller
|
||||
$destinations = app(ContentManagement::class)->access($actor);
|
||||
$data = ['items' => $items, 'filters' => $filters, 'notices' => $workflow->notices($actor), 'resourceAccess' => $access->full($actor) || $access->editorial($actor), 'opportunitiesUrl' => $destinations['opportunities']['index'] ?? null,
|
||||
'offersUrl' => isset($destinations['opportunities']['index']) && app(PortalProfileAccess::class)->available() ? '/minhas-oportunidades/ofertas' : null,
|
||||
'offerOperationsUrl' => ! app(PortalProfileAccess::class)->has($actor, 'auditor') && (app(PortalProfileAccess::class)->has($actor, 'validator') || app(PortalProfileAccess::class)->has($actor, 'publisher')) ? '/minhas-oportunidades/ofertas?operational=1' : null,
|
||||
'opportunityPending' => $workflow->opportunityPending($actor), 'clustersUrl' => $destinations['clusters']['index'] ?? null,
|
||||
'portfolioUrl' => $destinations['portfolio']['index'] ?? null, 'portfolioPending' => $workflow->portfolioPending($actor), 'demographyUrl' => $destinations['demography']['index'] ?? null, 'demographyPending' => $workflow->demographyPending($actor),
|
||||
'territorialUrl' => app(TerritorialRegistry::class)->editorialAvailable() && $actor->can('manage-portal') ? '/management/territorial/editorial' : null,
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Opportunity;
|
||||
use App\Services\PrivateOfferOperations;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
final class PrivateOfferOperationsController extends Controller
|
||||
{
|
||||
public function show(Request $request, int $id, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
return response()->json($operations->presentation($request->user(), $id));
|
||||
}
|
||||
|
||||
public function owner(Request $request, int $id, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
$operations->ownerAction($request->user(), $id, $request->all());
|
||||
|
||||
return response()->json($operations->presentation($request->user(), $id));
|
||||
}
|
||||
|
||||
public function reportForm(Request $request, int $id, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
$record = Opportunity::findOrFail($id);
|
||||
abort_unless($record->isPrivateOfferPreparation() && $operations->canReport($request->user(), $record), 404);
|
||||
|
||||
return Inertia::render('offers/report', ['offerId' => $id])->toResponse($request);
|
||||
}
|
||||
|
||||
public function report(Request $request, int $id, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
return response()->json($operations->report($request->user(), $id, $request->all()), 201);
|
||||
}
|
||||
|
||||
public function handleReport(Request $request, int $id, string $reportId, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
$operations->handleReport($request->user(), $id, $reportId, $request->all());
|
||||
|
||||
return response()->json($operations->presentation($request->user(), $id));
|
||||
}
|
||||
|
||||
public function highlight(Request $request, int $id, PrivateOfferOperations $operations): Response
|
||||
{
|
||||
$operations->highlight($request->user(), $id, $request->all());
|
||||
|
||||
return response()->json($operations->presentation($request->user(), $id));
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user