146 lines
5.6 KiB
PHP
146 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace Modules\AssetExchange\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\AssetExchange\Http\Controllers\Concerns\AuthorizesAssetExchange;
|
|
use Modules\AssetExchange\Models\Deal;
|
|
use Modules\AssetExchange\Models\Listing;
|
|
use Modules\AssetExchange\Models\Offer;
|
|
use Modules\AssetExchange\Utils\AssetExchangeUtil;
|
|
use Yajra\DataTables\Facades\DataTables;
|
|
|
|
class OfferController extends Controller
|
|
{
|
|
use AuthorizesAssetExchange;
|
|
|
|
public function __construct(
|
|
protected AssetExchangeUtil $aexUtil
|
|
) {
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$this->authorizeAexAccess('aex.offers.view');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
|
|
if ($request->ajax()) {
|
|
$query = Offer::where('business_id', $business_id)
|
|
->with(['listing:id,title,listing_code', 'buyer:id,name', 'deal:id,deal_code'])
|
|
->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('buyer_name', fn ($row) => $row->buyer?->name ?? '—')
|
|
->addColumn('amount_fmt', fn ($row) => $this->aexUtil->formatMoney($row->amount))
|
|
->addColumn('status_label', fn ($row) => $this->aexUtil->statusLabel($row->status))
|
|
->addColumn('expires_at_fmt', fn ($row) => $this->aexUtil->formatDateTime($row->expires_at))
|
|
->addColumn('action', function ($row) {
|
|
$html = '<div class="btn-group">';
|
|
if ($row->status === 'pending' && auth()->user()->can('aex.offers.manage')) {
|
|
$html .= '<button type="button" data-href="'.action([self::class, 'accept'], [$row->id]).'" class="btn btn-xs btn-success aex_accept_offer"><i class="fa fa-check"></i></button>';
|
|
$html .= ' <button type="button" data-href="'.action([self::class, 'reject'], [$row->id]).'" class="btn btn-xs btn-danger aex_reject_offer"><i class="fa fa-times"></i></button>';
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
})
|
|
->rawColumns(['action'])
|
|
->make(true);
|
|
}
|
|
|
|
return view('assetexchange::offers.index', [
|
|
'statuses' => $this->aexUtil->statusLabels(),
|
|
'listings' => Listing::where('business_id', $business_id)
|
|
->whereIn('status', ['appraised', 'in_deal'])
|
|
->pluck('title', 'id'),
|
|
'contacts' => $this->aexUtil->getContactsDropdown($business_id),
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$this->authorizeAexAccess('aex.offers.create');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
|
|
$data = $request->validate([
|
|
'listing_id' => 'required|exists:aex_listings,id',
|
|
'deal_id' => 'nullable|exists:aex_deals,id',
|
|
'buyer_contact_id' => 'nullable|exists:contacts,id',
|
|
'amount' => 'required|integer|min:1',
|
|
'message' => 'nullable|string|max:2000',
|
|
'expires_at' => 'nullable|string',
|
|
]);
|
|
|
|
Listing::where('business_id', $business_id)->findOrFail($data['listing_id']);
|
|
|
|
if (! empty($data['deal_id'])) {
|
|
Deal::where('business_id', $business_id)->findOrFail($data['deal_id']);
|
|
}
|
|
|
|
$offer = Offer::create([
|
|
'business_id' => $business_id,
|
|
'listing_id' => $data['listing_id'],
|
|
'deal_id' => $data['deal_id'] ?? null,
|
|
'buyer_contact_id' => $data['buyer_contact_id'] ?? null,
|
|
'amount' => (int) $data['amount'],
|
|
'status' => 'pending',
|
|
'message' => $data['message'] ?? null,
|
|
'expires_at' => $this->aexUtil->parseInputDateTime($data['expires_at'] ?? null),
|
|
]);
|
|
|
|
return $this->aexUtil->jsonOrRedirect(
|
|
$request,
|
|
true,
|
|
__('assetexchange::lang.offer_created'),
|
|
action([self::class, 'index'])
|
|
);
|
|
}
|
|
|
|
public function accept(Request $request, $id)
|
|
{
|
|
$this->authorizeAexAccess('aex.offers.manage');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$offer = Offer::where('business_id', $business_id)->findOrFail($id);
|
|
|
|
if ($offer->status !== 'pending') {
|
|
return $this->aexUtil->jsonOrRedirect($request, false, __('assetexchange::lang.offer_not_pending'));
|
|
}
|
|
|
|
$offer->update(['status' => 'accepted']);
|
|
|
|
if ($offer->deal_id) {
|
|
Deal::where('id', $offer->deal_id)->update([
|
|
'agreed_price' => $offer->amount,
|
|
'buyer_contact_id' => $offer->buyer_contact_id ?: Deal::where('id', $offer->deal_id)->value('buyer_contact_id'),
|
|
]);
|
|
}
|
|
|
|
return $this->aexUtil->jsonOrRedirect($request, true, __('assetexchange::lang.offer_accepted'));
|
|
}
|
|
|
|
public function reject(Request $request, $id)
|
|
{
|
|
$this->authorizeAexAccess('aex.offers.manage');
|
|
|
|
$business_id = $this->aexUtil->getBusinessId();
|
|
$offer = Offer::where('business_id', $business_id)->findOrFail($id);
|
|
|
|
if ($offer->status !== 'pending') {
|
|
return $this->aexUtil->jsonOrRedirect($request, false, __('assetexchange::lang.offer_not_pending'));
|
|
}
|
|
|
|
$offer->update(['status' => 'declined']);
|
|
|
|
return $this->aexUtil->jsonOrRedirect($request, true, __('assetexchange::lang.offer_rejected'));
|
|
}
|
|
}
|