authorizeAexAccess('aex.appraisals.view'); $business_id = $this->aexUtil->getBusinessId(); if ($request->ajax()) { $query = Appraisal::where('business_id', $business_id) ->with(['listing:id,title,listing_code', 'appraiser:id,first_name,last_name,surname']) ->orderByDesc('created_at'); if ($status = $request->get('status')) { $query->where('status', $status); } return DataTables::of($query) ->addColumn('listing_title', fn ($row) => $row->listing?->title ?? '—') ->addColumn('listing_code', fn ($row) => $row->listing?->listing_code ?? '—') ->addColumn('appraiser_name', fn ($row) => $row->appraiser?->user_full_name ?? $row->appraiser?->first_name ?? '—') ->addColumn('status_label', fn ($row) => $this->aexUtil->statusLabel($row->status)) ->addColumn('as_is_fmt', fn ($row) => $this->aexUtil->formatMoney($row->as_is_value)) ->addColumn('action', function ($row) { $html = '
'; $html .= ''; if (auth()->user()->can('aex.appraisals.update')) { $html .= ' '; } $html .= '
'; return $html; }) ->rawColumns(['action']) ->make(true); } return view('assetexchange::appraisals.index', [ 'statuses' => $this->aexUtil->statusLabels(), ]); } public function create(Request $request) { $this->authorizeAexAccess('aex.appraisals.create'); $business_id = $this->aexUtil->getBusinessId(); $listing_id = $request->integer('listing_id') ?: null; $listing = null; if ($listing_id) { $listing = Listing::where('business_id', $business_id)->findOrFail($listing_id); } $listings = Listing::where('business_id', $business_id) ->whereIn('status', ['submitted', 'under_review', 'appraised', 'in_deal']) ->orderByDesc('id') ->pluck('title', 'id'); return view('assetexchange::appraisals.create', compact('listing', 'listings')); } public function store(Request $request) { $this->authorizeAexAccess('aex.appraisals.create'); $business = $this->aexUtil->getBusiness(); if (! $business) { abort(404); } $data = $request->validate([ 'listing_id' => 'required|exists:aex_listings,id', 'methodology' => 'nullable|string|max:50', 'field_visit_date' => 'nullable|string', 'appraisal_fee' => 'nullable|integer|min:0', 'auto_import' => 'sometimes|boolean', ]); $listing = Listing::where('business_id', $business->id)->findOrFail($data['listing_id']); $options = [ 'methodology' => $data['methodology'] ?? null, 'field_visit_date' => $this->aexUtil->parseInputDate($data['field_visit_date'] ?? null), 'appraisal_fee' => $data['appraisal_fee'] ?? null, 'auto_import' => $request->boolean('auto_import', true), ]; try { $appraisal = $this->appraisalService->startAppraisal($business, $listing, auth()->user(), $options); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.appraisal_started'), action([self::class, 'workspace'], [$appraisal->id]) ); } public function show($id) { $this->authorizeAexAccess('aex.appraisals.view'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id) ->with(['listing.seller', 'appraiser', 'approvedByUser', 'lines']) ->findOrFail($id); return view('assetexchange::appraisals.show', compact('appraisal')); } public function workspace($id) { $this->authorizeAexAccess('aex.appraisals.update'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id) ->with(['listing', 'lines.childLines']) ->findOrFail($id); $lineTree = $appraisal->lines->whereNull('parent_line_id'); return view('assetexchange::appraisals.workspace', compact('appraisal', 'lineTree')); } public function importIe(Request $request, $id) { $this->authorizeAexAccess('aex.appraisals.update'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id)->findOrFail($id); $data = $request->validate([ 'bom_id' => 'nullable|integer', 'replace_existing' => 'sometimes|boolean', ]); try { $count = $this->appraisalService->importFromIeBom( $appraisal, $data['bom_id'] ?? null, $request->boolean('replace_existing') ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.ie_imported', ['count' => $count]), action([self::class, 'workspace'], [$appraisal->id]) ); } public function importCmms(Request $request, $id) { $this->authorizeAexAccess('aex.appraisals.update'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id)->findOrFail($id); $data = $request->validate([ 'equipment_id' => 'nullable|integer', 'replace_existing' => 'sometimes|boolean', ]); try { $count = $this->appraisalService->importFromCmmsEquipmentParts( $appraisal, $data['equipment_id'] ?? null, $request->boolean('replace_existing') ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.cmms_imported', ['count' => $count]), action([self::class, 'workspace'], [$appraisal->id]) ); } public function recalculate(Request $request, $id) { $this->authorizeAexAccess('aex.appraisals.update'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id)->findOrFail($id); try { $appraisal = $this->appraisalService->recalculate($appraisal); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.appraisal_recalculated'), action([self::class, 'workspace'], [$appraisal->id]) ); } public function approve(Request $request, $id) { $this->authorizeAexAccess('aex.appraisals.approve'); $business = $this->aexUtil->getBusiness(); $appraisal = Appraisal::where('business_id', $business->id)->findOrFail($id); $data = $request->validate([ 'report_summary' => 'nullable|string', ]); try { $appraisal = $this->appraisalService->approve( $business, $appraisal, auth()->user(), $data['report_summary'] ?? null ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.appraisal_approved'), action([self::class, 'show'], [$appraisal->id]) ); } public function report($id) { $this->authorizeAexAccess('aex.appraisals.view'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id)->findOrFail($id); $html = $this->appraisalService->generateReportHtml($appraisal); return response($html)->header('Content-Type', 'text/html; charset=UTF-8'); } public function reportPdf($id) { $this->authorizeAexAccess('aex.appraisals.view'); $business_id = $this->aexUtil->getBusinessId(); $appraisal = Appraisal::where('business_id', $business_id)->findOrFail($id); $this->appraisalService->storeReportPdf($appraisal); $pdfBinary = $this->appraisalService->renderReportPdf($appraisal->fresh()); $fileName = 'appraisal-'.$appraisal->appraisal_number.'.pdf'; return Response::make($pdfBinary, 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'attachment; filename="'.$fileName.'"', ]); } }