authorizeResource(Claim::class); } /** * Display a listing of the resource. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Contracts\View\View */ public function index(Request $request): \Illuminate\Contracts\View\View { /** @var \App\Models\User $userModel */ $userModel = auth('backend')->user(); /** @var \Illuminate\Database\Eloquent\Builder $query */ $query = Claim::query() ->when( $request->filled('brand'), fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand)) )->when( $userModel->role->equals(RoleEnum::marketing), fn($q) => $q->whereHas('brand', fn($q) => $q->whereIn('id', $userModel->brands->modelKeys())) ) ->when( $request->filled('subject'), fn($q) => $q->whereHas('claimSubject', fn($q) => $q->where('id', $request->subject)) ) ->when( $request->filled('status'), fn($q) => $q->whereIn('status', $request->status), fn($q) => $q->whereNotIn('status', [ClaimStatus::treated, ClaimStatus::refused]) ); /** @var string $search Search field */ $search = $request->search; if ($search) { $this->searchQuery( $query, $search, null, 'reference', 'first_name', 'last_name', 'email', ); } $searchFields = \implode(', ', [ trans('validation.custom.reference'), trans('validation.attributes.first_name'), trans('validation.attributes.last_name'), trans('validation.attributes.email'), ]); /** Sort columns with a query */ $this->sortQuery($query); /** Custom pagination */ $claimModels = $query->simplePaginate($this->getPagination()); /** Define request brand filter if user only has 1 brand */ if (auth('backend')->user()->brands()->count() === 1) { $request->merge(['brand' => auth('backend')->user()->brands()->value('id')]); }; $claimSubjectModels = ClaimSubject::query() ->when( $request->filled('brand'), fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand)), ) ->when( auth('backend')->user()->brands()->count() === 1, fn($q) => $q->whereHas( 'brand', fn($q) => $q->where('id', auth('backend')->user()->brands()->pluck('id')) ) ); $claimSubjectModels = $request->filled('brand') || (auth('backend')->user()->brands()->count() === 1) ? $claimSubjectModels->orderBy('label', 'ASC')->get() : null; return view('bo.pages.claims.index', compact('claimModels', 'search', 'searchFields', 'claimSubjectModels')); } /** * Show the form for editing the specified resource. * * @param App\Models\Claim $claim * @return \Illuminate\Contracts\View\View */ public function edit(Claim $claim): \Illuminate\Contracts\View\View { $customerClaimModels = !is_null($claim->customerInfos) ? Claim::query() ->where('hashcode', $claim->customerInfos->hashcode) ->whereHas('brand', fn($q) => $q->whereKey($claim->brand->getKey())) ->whereNot('id', $claim->getKey()) ->paginate($this->jsonItemPerPagination) : collect(); $brandModels = CollectionHelper::paginate( Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination, ); $claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey()); $claimSubjectModels = CollectionHelper::paginate( ClaimSubject::getAllModelsFromBrand($claim->brand->getKey()), $this->jsonItemPerPagination, ); $claimTemplateModels = CollectionHelper::paginate( ClaimMailTemplate::getAllModelsFromBrand($claim->brand->getKey()), $this->jsonItemPerPagination, ); return view('bo.pages.claims.edit', [ 'claimModel' => $claim->load(['brand', 'claimSubject']), 'customerClaimModels' => $customerClaimModels, 'brandModels' => $brandModels, 'claimMessageModels' => $claimMessageModels, 'claimSubjectModels' => $claimSubjectModels, 'claimTemplateModels' => $claimTemplateModels, 'customerInfoModel' => $claim->customerInfos, ]); } /** * Update the specified resource. * * @param \App\Http\Requests\Bo\Claims\UpdateClaimRequest $request * @param \App\Models\Claim $claim * @return \Illuminate\Http\JsonResponse */ public function update(UpdateClaimRequest $request, Claim $claim): \Illuminate\Http\JsonResponse { return DB::transaction(function () use ($request, $claim) { $claim->fill($request->validated()); if ($claim->saveOrFail()) { $claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey()); return response()->json($claimMessageModels); } return response()->json([], 500); }); } /** * Send the claim answer. * * @param \App\Http\Requests\Bo\Claims\SendClaimAnswerRequest $request * @param \App\Models\Claim $claim * @return \Illuminate\Http\JsonResponse */ public function answer(SendClaimAnswerRequest $request, Claim $claim): \Illuminate\Http\JsonResponse { return DB::transaction(function () use ($request, $claim) { /** @var \App\Models\User $userModel */ $userModel = auth()->user(); $enum = ClaimResponseType::manual; $claim->response_type = $enum; $claim->status = ClaimStatus::treated; if ($claim->saveOrFail()) { // Send the response to the claim author. Mail::to($claim->email)->send(new ClaimAnswerMail($claim, $request->validated()['content'])); // Create custom event with content message. // @phpcs:disable Generic.Files.LineLength.TooLong $content = sprintf( "%s %s %s %s
%s", $userModel->first_name, $userModel->last_name, trans('a modifié :field en', ['field' => trans('validation.custom.response_type')]), $claim->response_type->label(), clean($request->validated()['content']), ); event(new ClaimModelChanged($claim, '', '', null, $content)); // @phpcs:enable // Return conversation. $claimMessageModels = ClaimMessage::getAllModelsFromClaim($claim->getKey()); return response()->json($claimMessageModels); } //end if return response()->json([], 500); }); } /** * Undocumented function * * @param ViewClaimAttachmentRequest $request * @param Claim $claim * @return \Symfony\Component\HttpFoundation\BinaryFileResponse * * @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter */ public function viewAttachment( ViewClaimAttachmentRequest $request, Claim $claim ): \Symfony\Component\HttpFoundation\BinaryFileResponse { // phpcs:enable return response()->file(Storage::disk('private')->path(FileHelper::getPrivateFilePath($claim->file))); } /** * Get a paginate resource. * Needed to overheight the controller method and add a brand condition. * * @param \App\Http\Requests\Bo\PaginateModelsRequest $request * @return \Illuminate\Http\JsonResponse */ public function jsonClaimPaginateModels(PaginateModelsRequest $request): \Illuminate\Http\JsonResponse { $data = $request->validated(); $brandModelKey = $request->route()->parameter('brand')->getKey(); $models = CollectionHelper::paginateManually( $data['targetModel']::getAllModelsFromBrand($brandModelKey), $this->jsonItemPerPagination, $request->validated('page'), ); return \response()->json($models); } // * EXPORT /** * Export claim datas to a given format * * @param ExportClaimRequest $request * @return \Illuminate\Http\Response|Symfony\Component\HttpFoundation\StreamedResponse|\Illuminate\Http\RedirectResponse */ public function export(ExportClaimRequest $request) { /** @var \Illuminate\Database\Eloquent\Collection $claims*/ $claims = Claim::query()->whereIn('id', $request->validated('claimList'))->get(); $format = ExportFormat::from($request->validated('format')); // * CSV if ($format->equals(ExportFormat::csvWithoutAttachment, ExportFormat::csv)) { $csv = $this->generateCsv($claims); if (!$this->needsZip($format, $claims)) { return new StreamedResponse(function () use ($format, $csv) { echo $csv; }, 200, $this->getFileHeaders($format)); } return $this->returnExportZip($format, $claims, $csv); // * PDF } elseif ($format->equals(ExportFormat::pdf)) { $pdf = $this->generatePdf($claims); if (!$this->needsZip(ExportFormat::pdf, $claims)) { return $pdf->download('export.pdf'); } return $this->returnExportZip($format, $claims, $pdf->output()); }; //end if } }