feat: add withdraw request functionality and UI components
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\WithdrawRequestStatusEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\WithdrawRejectRequest;
|
||||
use App\Http\Resources\Admin\WithdrawRequestResource;
|
||||
use App\Models\WithdrawRequest;
|
||||
use App\Services\Wallet\WalletService;
|
||||
use App\Services\Wallet\WithdrawRequestService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class WithdrawRequestController extends Controller
|
||||
{
|
||||
protected WithdrawRequestService $withdrawRequestService;
|
||||
|
||||
protected WalletService $walletService;
|
||||
|
||||
public function __construct(WithdrawRequestService $withdrawRequestService, WalletService $walletService)
|
||||
{
|
||||
$this->withdrawRequestService = $withdrawRequestService;
|
||||
$this->walletService = $walletService;
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$lists = WithdrawRequest::with(['user', 'bankCard', 'reviewedBy'])
|
||||
->when(isset($request->search), function ($query) use ($request) {
|
||||
$query->whereHas('user', function ($userQuery) use ($request) {
|
||||
$userQuery->where('fullname', 'LIKE', "%{$request->search}%")
|
||||
->orWhere('phone', 'LIKE', "%{$request->search}%")
|
||||
->orWhere('email', 'LIKE', "%{$request->search}%");
|
||||
});
|
||||
})
|
||||
->when(isset($request->status) && $request->status != 'همه وضعیت ها', function ($query) use ($request) {
|
||||
$query->where('status', $request->status);
|
||||
})
|
||||
->latest()
|
||||
->paginate(20)
|
||||
->withQueryString()
|
||||
->onEachSide(1);
|
||||
|
||||
$pending = WithdrawRequest::where('status', WithdrawRequestStatusEnum::Pending->value);
|
||||
|
||||
return Inertia::admin('WithdrawRequests/index', [
|
||||
'withdrawRequests' => WithdrawRequestResource::collection($lists),
|
||||
'stats' => [
|
||||
'pending_count' => (clone $pending)->count(),
|
||||
'pending_amount' => (int) (clone $pending)->sum('amount'),
|
||||
'system_wallet_balance' => $this->walletService->system()->balance,
|
||||
],
|
||||
'search' => $request->search,
|
||||
'status' => $request->status,
|
||||
]);
|
||||
}
|
||||
|
||||
public function approve(WithdrawRequest $withdrawRequest)
|
||||
{
|
||||
$this->withdrawRequestService->approve($withdrawRequest, Auth::user());
|
||||
|
||||
session()->flash('success', 'درخواست برداشت تایید شد و مبلغ به ولت سایت منتقل شد.');
|
||||
|
||||
return response(null, 200);
|
||||
}
|
||||
|
||||
public function reject(WithdrawRejectRequest $request, WithdrawRequest $withdrawRequest)
|
||||
{
|
||||
$this->withdrawRequestService->reject($withdrawRequest, Auth::user(), $request->validated('note'));
|
||||
|
||||
session()->flash('success', 'درخواست برداشت رد شد.');
|
||||
|
||||
return response(null, 200);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,10 @@
|
||||
namespace App\Http\Controllers\Client\Doctor;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Client\CaseRejectRequest;
|
||||
use App\Http\Resources\Client\CaseDetailResource;
|
||||
use App\Http\Resources\Client\CaseResource;
|
||||
use App\Models\Document;
|
||||
use App\Services\Document\CaseService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
@@ -28,4 +31,25 @@ class CaseController extends Controller
|
||||
'cases' => CaseResource::collection($cases),
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Document $case)
|
||||
{
|
||||
abort_unless($this->caseService->canAccess($case, Auth::user()), 403);
|
||||
|
||||
$case->load(['pet', 'requester', 'media', 'reports']);
|
||||
|
||||
return Inertia::client('Dashboard/Cases/show', [
|
||||
'case' => (new CaseDetailResource($case))->resolve(),
|
||||
'canReport' => $this->caseService->canReport($case, Auth::user()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function reject(CaseRejectRequest $request, Document $case)
|
||||
{
|
||||
$this->caseService->reject($case, Auth::user(), $request->validated('reason'));
|
||||
|
||||
session()->flash('success', 'درخواست رد شد و مبلغ فاکتور به کیف پول درخواستکننده بازگردانده شد.');
|
||||
|
||||
return redirect()->route('dashboard.cases.index');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ class DashboardController extends Controller
|
||||
|
||||
return Inertia::client('Dashboard/Dashboard', [
|
||||
'cases' => CaseResource::collection($cases),
|
||||
'stats' => $this->caseService->statsForUser(Auth::user()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ class DocumentController extends Controller
|
||||
|
||||
public function show(Document $document)
|
||||
{
|
||||
return Inertia::client('Dashboard/Documents/show', [
|
||||
'document' => $document,
|
||||
]);
|
||||
return redirect()->route('dashboard.cases.show', $document);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,53 @@
|
||||
namespace App\Http\Controllers\Client\Doctor;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\Client\ReportSubmitRequest;
|
||||
use App\Http\Resources\Client\ReportResource;
|
||||
use App\Models\Document;
|
||||
use App\Models\Report;
|
||||
use App\Services\Document\CaseService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
protected CaseService $caseService;
|
||||
|
||||
public function __construct(CaseService $caseService)
|
||||
{
|
||||
$this->caseService = $caseService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return Inertia::client('Dashboard/Reports/Index');
|
||||
$reports = Report::with(['document', 'doctor'])
|
||||
->where(function ($query) {
|
||||
$query->where('doctor_id', Auth::id())
|
||||
->orWhereHas('document', fn ($documentQuery) => $documentQuery->where('requester_id', Auth::id()));
|
||||
})
|
||||
->latest('submitted_at')
|
||||
->paginate(10)
|
||||
->withQueryString()
|
||||
->onEachSide(1);
|
||||
|
||||
return Inertia::client('Dashboard/Reports/Index', [
|
||||
'reports' => ReportResource::collection($reports),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(ReportSubmitRequest $request)
|
||||
{
|
||||
$document = Document::findOrFail($request->validated('document_id'));
|
||||
|
||||
$this->caseService->submitReport(
|
||||
$document,
|
||||
Auth::user(),
|
||||
$request->validated(),
|
||||
$request->file('files', [])
|
||||
);
|
||||
|
||||
session()->flash('success', 'گزارش با موفقیت ثبت شد.');
|
||||
|
||||
return redirect()->route('dashboard.cases.index');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class FastRequestController extends Controller
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'document' => new FastRequestResource($document->refresh()->load('pet')),
|
||||
'document' => new FastRequestResource($document->refresh()->load(['pet', 'invoice'])),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Client;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\Client\InvoiceResource;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\Wallet\WalletService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class InvoiceController extends Controller
|
||||
{
|
||||
protected WalletService $walletService;
|
||||
|
||||
public function __construct(WalletService $walletService)
|
||||
{
|
||||
$this->walletService = $walletService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$invoices = Auth::user()->invoices()
|
||||
->with('document')
|
||||
->latest()
|
||||
->paginate(10)
|
||||
->withQueryString()
|
||||
->onEachSide(1);
|
||||
|
||||
return Inertia::client('Dashboard/Invoices/Index', [
|
||||
'invoices' => InvoiceResource::collection($invoices),
|
||||
]);
|
||||
}
|
||||
|
||||
public function payWithWallet(Invoice $invoice)
|
||||
{
|
||||
abort_unless($invoice->user_id === Auth::id(), 403);
|
||||
|
||||
$invoice = $this->walletService->payInvoice(Auth::user(), $invoice);
|
||||
|
||||
return response()->json([
|
||||
'invoice' => new InvoiceResource($invoice),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Client;
|
||||
|
||||
use App\Enums\InvoicePaymentMethodEnum;
|
||||
use App\Enums\InvoiceStatusEnum;
|
||||
use App\Enums\PaymentPurposeEnum;
|
||||
use App\Enums\PaymentStatusEnum;
|
||||
use App\Enums\WalletTransactionReasonEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Client\PaymentRequest;
|
||||
use App\Http\Resources\Client\PaymentResource;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Services\Invoice\InvoiceService;
|
||||
use App\Services\Payment\ZibalPaymentService;
|
||||
use App\Services\Wallet\WalletService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
protected ZibalPaymentService $zibalPaymentService;
|
||||
|
||||
protected WalletService $walletService;
|
||||
|
||||
protected InvoiceService $invoiceService;
|
||||
|
||||
public function __construct(ZibalPaymentService $zibalPaymentService, WalletService $walletService, InvoiceService $invoiceService)
|
||||
{
|
||||
$this->zibalPaymentService = $zibalPaymentService;
|
||||
$this->walletService = $walletService;
|
||||
$this->invoiceService = $invoiceService;
|
||||
}
|
||||
|
||||
public function store(PaymentRequest $request)
|
||||
{
|
||||
$invoice = Invoice::where('id', $request->invoice_id)
|
||||
->where('user_id', Auth::id())
|
||||
->where('status', InvoiceStatusEnum::Pending->value)
|
||||
->firstOrFail();
|
||||
|
||||
$payment = $this->zibalPaymentService->request(Auth::user(), $invoice->amount, $invoice->number, [
|
||||
'purpose' => PaymentPurposeEnum::Invoice->value,
|
||||
'invoice_id' => $invoice->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'payment' => new PaymentResource($payment),
|
||||
'url' => $this->zibalPaymentService->paymentUrl($payment),
|
||||
]);
|
||||
}
|
||||
|
||||
public function callback(Request $request)
|
||||
{
|
||||
$payment = Payment::where('track_id', $request->trackId)->first();
|
||||
|
||||
if (!$payment) {
|
||||
return redirect()->route('dashboard.index');
|
||||
}
|
||||
|
||||
$wasPending = $payment->status === PaymentStatusEnum::Pending;
|
||||
|
||||
if ($request->success == 1) {
|
||||
$payment = $this->zibalPaymentService->verify($payment);
|
||||
} else {
|
||||
$payment = $this->zibalPaymentService->markFailed($payment);
|
||||
}
|
||||
|
||||
if ($wasPending && $payment->status === PaymentStatusEnum::Paid) {
|
||||
$this->settle($payment);
|
||||
}
|
||||
|
||||
session()->flash('payment_result', [
|
||||
'status' => $payment->status === PaymentStatusEnum::Paid ? 'paid' : 'failed',
|
||||
'track_id' => $payment->track_id,
|
||||
'purpose' => $payment->purpose->name,
|
||||
]);
|
||||
|
||||
return redirect()->route('dashboard.index');
|
||||
}
|
||||
|
||||
protected function settle(Payment $payment): void
|
||||
{
|
||||
if ($payment->purpose === PaymentPurposeEnum::WalletTopUp) {
|
||||
$this->walletService->deposit($payment->payer, $payment->amount, WalletTransactionReasonEnum::TopUp, $payment);
|
||||
return;
|
||||
}
|
||||
|
||||
$invoice = $payment->invoice;
|
||||
|
||||
if ($invoice && $invoice->status === InvoiceStatusEnum::Pending) {
|
||||
$this->invoiceService->markPaid($invoice, InvoicePaymentMethodEnum::Gateway);
|
||||
$this->walletService->recordGatewayInvoicePayment($invoice, $payment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Client;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Client\ProfileUpdateRequest;
|
||||
use App\Models\Medium;
|
||||
use App\Services\FileStorageService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
protected FileStorageService $fileStorageService;
|
||||
|
||||
public function __construct(FileStorageService $fileStorageService)
|
||||
{
|
||||
$this->fileStorageService = $fileStorageService;
|
||||
}
|
||||
|
||||
public function update(ProfileUpdateRequest $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$data = $request->safe()->except('avatar');
|
||||
|
||||
if ($request->hasFile('avatar')) {
|
||||
if (!empty($user->profile_url)) {
|
||||
if ($medium = Medium::where('url', $user->profile_url)->first()) {
|
||||
$this->fileStorageService->deleteMedium($medium);
|
||||
}
|
||||
}
|
||||
|
||||
$medium = $this->fileStorageService->storeFile($request->file('avatar'), 'public', 'profile');
|
||||
$data['profile_url'] = $medium->url;
|
||||
}
|
||||
|
||||
$user->update($data);
|
||||
|
||||
session()->flash('success', 'حساب کاربری شما با موفقیت ویرایش شد.');
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Client;
|
||||
|
||||
use App\Enums\PaymentPurposeEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Client\BankCardStoreRequest;
|
||||
use App\Http\Requests\Client\WalletDepositRequest;
|
||||
use App\Http\Requests\Client\WithdrawRequestStoreRequest;
|
||||
use App\Http\Resources\Client\BankCardResource;
|
||||
use App\Http\Resources\Client\PaymentResource;
|
||||
use App\Http\Resources\Client\WalletTransactionResource;
|
||||
use App\Http\Resources\Client\WithdrawRequestResource;
|
||||
use App\Models\BankCard;
|
||||
use App\Services\Payment\ZibalPaymentService;
|
||||
use App\Services\Wallet\WalletService;
|
||||
use App\Services\Wallet\WithdrawRequestService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class WalletController extends Controller
|
||||
{
|
||||
protected WalletService $walletService;
|
||||
|
||||
protected ZibalPaymentService $zibalPaymentService;
|
||||
|
||||
protected WithdrawRequestService $withdrawRequestService;
|
||||
|
||||
public function __construct(WalletService $walletService, ZibalPaymentService $zibalPaymentService, WithdrawRequestService $withdrawRequestService)
|
||||
{
|
||||
$this->walletService = $walletService;
|
||||
$this->zibalPaymentService = $zibalPaymentService;
|
||||
$this->withdrawRequestService = $withdrawRequestService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$wallet = $this->walletService->forUser(Auth::user());
|
||||
|
||||
$transactions = $wallet->transactions()
|
||||
->with('invoice')
|
||||
->latest()
|
||||
->paginate(10)
|
||||
->withQueryString()
|
||||
->onEachSide(1);
|
||||
|
||||
$withdrawRequests = Auth::user()->withdrawRequests()
|
||||
->with('bankCard')
|
||||
->latest()
|
||||
->take(10)
|
||||
->get();
|
||||
|
||||
return Inertia::client('Dashboard/Wallet/Index', [
|
||||
'transactions' => WalletTransactionResource::collection($transactions),
|
||||
'withdrawRequests' => WithdrawRequestResource::collection($withdrawRequests)->resolve(),
|
||||
'bankCards' => BankCardResource::collection(Auth::user()->bankCards()->latest()->get())->resolve(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function deposit(WalletDepositRequest $request)
|
||||
{
|
||||
$payment = $this->zibalPaymentService->request(
|
||||
Auth::user(),
|
||||
$request->validated('amount'),
|
||||
'wallet-' . Auth::id() . '-' . now()->timestamp,
|
||||
['purpose' => PaymentPurposeEnum::WalletTopUp->value]
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'payment' => new PaymentResource($payment),
|
||||
'url' => $this->zibalPaymentService->paymentUrl($payment),
|
||||
]);
|
||||
}
|
||||
|
||||
public function storeWithdrawRequest(WithdrawRequestStoreRequest $request)
|
||||
{
|
||||
$bankCard = BankCard::findOrFail($request->validated('bank_card_id'));
|
||||
|
||||
$this->withdrawRequestService->request(Auth::user(), $request->validated('amount'), $bankCard);
|
||||
|
||||
session()->flash('success', 'درخواست برداشت شما ثبت شد و در انتظار بررسی است.');
|
||||
|
||||
return redirect()->route('dashboard.wallet.index');
|
||||
}
|
||||
|
||||
public function storeBankCard(BankCardStoreRequest $request)
|
||||
{
|
||||
Auth::user()->bankCards()->create($request->validated());
|
||||
|
||||
session()->flash('success', 'کارت بانکی با موفقیت ثبت شد.');
|
||||
|
||||
return redirect()->route('dashboard.wallet.index');
|
||||
}
|
||||
|
||||
public function destroyBankCard(BankCard $bankCard)
|
||||
{
|
||||
abort_unless($bankCard->user_id === Auth::id(), 403);
|
||||
|
||||
$bankCard->delete();
|
||||
|
||||
return redirect()->route('dashboard.wallet.index');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user