authorizeAexAccess('aex.deals.view'); $business_id = $this->aexUtil->getBusinessId(); if ($request->ajax()) { $query = Deal::where('business_id', $business_id) ->with(['listing:id,title,listing_code', 'buyer:id,name', 'appraisal:id,appraisal_number']) ->orderByDesc('created_at'); if ($status = $request->get('status')) { $query->where('status', $status); } if ($deal_type = $request->get('deal_type')) { $query->where('deal_type', $deal_type); } return DataTables::of($query) ->addColumn('listing_title', fn ($row) => $row->listing?->title ?? '—') ->addColumn('buyer_name', fn ($row) => $row->buyer?->name ?? '—') ->addColumn('type_label', fn ($row) => $this->aexUtil->dealTypeLabel($row->deal_type)) ->addColumn('status_label', fn ($row) => $this->aexUtil->statusLabel($row->status)) ->addColumn('agreed_price_fmt', fn ($row) => $this->aexUtil->formatMoney($row->agreed_price)) ->addColumn('action', function ($row) { $html = '
'; return $html; }) ->rawColumns(['action']) ->make(true); } return view('assetexchange::deals.index', [ 'statuses' => $this->aexUtil->statusLabels(), 'deal_types' => $this->aexUtil->dealTypeLabels(), ]); } public function create(Request $request) { $this->authorizeAexAccess('aex.deals.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) ->with('appraisals') ->findOrFail($listing_id); } $listings = Listing::where('business_id', $business_id) ->whereIn('status', ['appraised', 'in_deal']) ->orderByDesc('id') ->pluck('title', 'id'); return view('assetexchange::deals.create', [ 'listing' => $listing, 'listings' => $listings, 'deal_types' => $this->aexUtil->dealTypeLabels(), 'contacts' => $this->aexUtil->getContactsDropdown($business_id), ]); } public function store(Request $request) { $this->authorizeAexAccess('aex.deals.create'); $business = $this->aexUtil->getBusiness(); if (! $business) { abort(404); } $data = $request->validate([ 'listing_id' => 'required|exists:aex_listings,id', 'deal_type' => 'required|in:company_purchase,brokerage,appraisal_only,renovation_contract', 'buyer_contact_id' => 'nullable|exists:contacts,id', 'appraisal_id' => 'nullable|exists:aex_appraisals,id', 'agreed_price' => 'nullable|integer|min:0', 'commission_percent' => 'nullable|numeric|min:0|max:100', 'notes' => 'nullable|string', ]); $listing = Listing::where('business_id', $business->id)->findOrFail($data['listing_id']); try { $deal = $this->dealService->createDeal( $business, $listing, $data['deal_type'], $data, auth()->user() ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.deal_created'), action([self::class, 'show'], [$deal->id]) ); } public function show($id) { $this->authorizeAexAccess('aex.deals.view'); $business_id = $this->aexUtil->getBusinessId(); $deal = Deal::where('business_id', $business_id) ->with(['listing.seller', 'buyer', 'appraisal', 'offers', 'commissions.user']) ->findOrFail($id); return view('assetexchange::deals.show', compact('deal')); } public function update(Request $request, $id) { $this->authorizeAexAccess('aex.deals.update'); $business = $this->aexUtil->getBusiness(); $deal = Deal::where('business_id', $business->id)->findOrFail($id); $data = $request->validate([ 'status' => 'sometimes|in:negotiating,quoted,contracted,in_progress,completed,cancelled', 'agreed_price' => 'nullable|integer|min:0', 'commission_percent' => 'nullable|numeric|min:0|max:100', 'buyer_contact_id' => 'nullable|exists:contacts,id', 'notes' => 'nullable|string', ]); if (isset($data['status'])) { try { $deal = $this->dealService->updateStatus($business, $deal, $data['status'], auth()->user()); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } } $fillable = collect($data)->only(['agreed_price', 'commission_percent', 'buyer_contact_id', 'notes'])->toArray(); if (! empty($fillable)) { if (isset($fillable['commission_percent'])) { $fillable['commission_amount'] = (int) round( ($fillable['agreed_price'] ?? $deal->agreed_price) * ($fillable['commission_percent'] / 100) ); } $deal->update($fillable); $deal = $deal->fresh(); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.deal_updated'), action([self::class, 'show'], [$deal->id]) ); } public function complete(Request $request, $id) { $this->authorizeAexAccess('aex.deals.complete'); $business = $this->aexUtil->getBusiness(); $deal = Deal::where('business_id', $business->id)->findOrFail($id); try { $deal = $this->dealService->completeDeal($business, $deal, auth()->user()); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.deal_completed'), action([self::class, 'show'], [$deal->id]) ); } public function createPo(Request $request, $id) { $this->authorizeAexAccess('aex.deals.update'); $business = $this->aexUtil->getBusiness(); $deal = Deal::where('business_id', $business->id)->with('listing')->findOrFail($id); try { $transaction = $this->erpBridge->createPurchaseOrder( $business, $deal->listing, $deal, $request->integer('location_id') ?: null, auth()->user() ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.po_created', ['ref' => $transaction->ref_no ?? $transaction->id]), action([self::class, 'show'], [$deal->id]) ); } public function createQuotation(Request $request, $id) { $this->authorizeAexAccess('aex.deals.update'); $business = $this->aexUtil->getBusiness(); $deal = Deal::where('business_id', $business->id)->with('listing')->findOrFail($id); try { $transaction = $this->erpBridge->createQuotation( $business, $deal->listing, $deal, $request->integer('location_id') ?: null, auth()->user() ); } catch (\Throwable $e) { return $this->aexUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->aexUtil->jsonOrRedirect( $request, true, __('assetexchange::lang.quotation_created', ['ref' => $transaction->ref_no ?? $transaction->id]), action([self::class, 'show'], [$deal->id]) ); } }