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()); $claimSubjectModels = ClaimSubject::query() ->when( $request->filled('brand'), fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand)), fn($q) => $q->whereHas('brand', fn($q) => $q->whereIn('id', $userModel->brands()->pluck('id'))) ) ->get(); 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->customer) ? Claim::query() ->whereNotNull('customer_id') ->whereHas('brand', fn($q) => $q->whereKey($claim->brand->getKey())) ->whereHas('customer', fn($q) => $q->whereKey($claim->customer->getKey())) ->whereNot('id', $claim->getKey()) ->whereNot('status', ClaimStatus::treated)->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, ); $customerModel = CustomerInfo::query()->where('hashcode', $claim->hashcode)->first(); return view('bo.pages.claims.edit', [ 'claimModel' => $claim->load(['brand', 'claimSubject']), 'customerClaimModels' => $customerClaimModels, 'brandModels' => $brandModels, 'claimMessageModels' => $claimMessageModels, 'claimSubjectModels' => $claimSubjectModels, 'claimTemplateModels' => $claimTemplateModels, 'customerModel' => $customerModel, ]); } /** * 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); }); } /** * 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 /** * CSV File headers * * @var array */ private $header = [ "Prénom NOM", "Email", "Adresse", "Date de création", "Sujet", "Statut", "Message", "Pièce jointe", ]; public function export(ExportClaimRequest $request) { $claims = Claim::query()->whereIn('id', $request->validated('claimList'))->get(); $format = ClaimExportFormat::from($request->validated('format')); if ($format->equals(ClaimExportFormat::csv)) { $csvlines[] = $this->header; foreach ($claims as $claim) { $csvlines[] = $this->fillLine($claim); } return new StreamedResponse(function() use ($csvlines) { $this->array2csv($csvlines, ';'); }, 200, [ 'Content-Type' => 'text/csv', 'Content-Disposition' => 'attachment; filename="export.csv"', ]); } elseif ($format->equals(ClaimExportFormat::pdf)) { $pdf = Pdf::loadView('bo.pages.claims.pdf', [ 'claimModels' => $claims ]); return $pdf->download('export.pdf'); }; return back()->with('error', __('Une erreur est survenue lors de l\'export. Veuillez réessayer en rafraîchissant la page.')); } private function array2csv( array $lines, string $delimiter = ',', string $enclosure = '"', string $escape_char = "\\" ){ $f = fopen('php://output', 'w'); // UTF-8 BOM. $BOM = "\xEF\xBB\xBF"; fwrite($f, $BOM); foreach ($lines as $item) { fputcsv($f, $item, $delimiter, $enclosure, $escape_char); } fclose($f); } /** * fill one line for csv * @param \App\Models\Claim $claim * * @return array */ private function fillLine(Claim $claim) { $oneline = [ sprintf('%s %s', $claim->first_name, Str::upper($claim->last_name)), $claim->email, sprintf('%s, %s, %s', $claim->address, $claim->postcode, $claim->city), $claim->created_at->toDateTimeString(), $claim->claimSubject->label, $claim->status->label(), $claim->message, asset($claim->file), ]; return $oneline; } }