feat: add withdraw request functionality and UI components
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Wallet;
|
||||
|
||||
use App\Enums\WalletTransactionReasonEnum;
|
||||
use App\Enums\WithdrawRequestStatusEnum;
|
||||
use App\Models\BankCard;
|
||||
use App\Models\User;
|
||||
use App\Models\WithdrawRequest;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class WithdrawRequestService
|
||||
{
|
||||
protected WalletService $walletService;
|
||||
|
||||
public function __construct(WalletService $walletService)
|
||||
{
|
||||
$this->walletService = $walletService;
|
||||
}
|
||||
|
||||
public function request(User $user, int $amount, BankCard $bankCard): WithdrawRequest
|
||||
{
|
||||
if ($bankCard->user_id !== $user->id) {
|
||||
throw ValidationException::withMessages(['bank_card_id' => 'کارت بانکی انتخابشده معتبر نیست.']);
|
||||
}
|
||||
|
||||
$balance = $this->walletService->forUser($user)->balance;
|
||||
|
||||
$pendingAmount = WithdrawRequest::where('user_id', $user->id)
|
||||
->where('status', WithdrawRequestStatusEnum::Pending->value)
|
||||
->sum('amount');
|
||||
|
||||
if ($amount + $pendingAmount > $balance) {
|
||||
throw ValidationException::withMessages(['amount' => 'مجموع مبلغ درخواستهای برداشت از موجودی کیف پول شما بیشتر است.']);
|
||||
}
|
||||
|
||||
return WithdrawRequest::create([
|
||||
'amount' => $amount,
|
||||
'status' => WithdrawRequestStatusEnum::Pending->value,
|
||||
'user_id' => $user->id,
|
||||
'bank_card_id' => $bankCard->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function approve(WithdrawRequest $withdrawRequest, User $admin): WithdrawRequest
|
||||
{
|
||||
return DB::transaction(function () use ($withdrawRequest, $admin) {
|
||||
$this->ensurePending($withdrawRequest);
|
||||
|
||||
$this->walletService->withdraw(
|
||||
$withdrawRequest->user,
|
||||
$withdrawRequest->amount,
|
||||
WalletTransactionReasonEnum::Withdraw,
|
||||
null,
|
||||
$withdrawRequest
|
||||
);
|
||||
|
||||
$this->walletService->depositToWallet(
|
||||
$this->walletService->system(),
|
||||
$withdrawRequest->amount,
|
||||
WalletTransactionReasonEnum::Withdraw,
|
||||
null,
|
||||
$withdrawRequest
|
||||
);
|
||||
|
||||
$withdrawRequest->update([
|
||||
'status' => WithdrawRequestStatusEnum::Approved->value,
|
||||
'reviewed_at' => now(),
|
||||
'reviewed_by' => $admin->id,
|
||||
]);
|
||||
|
||||
return $withdrawRequest;
|
||||
});
|
||||
}
|
||||
|
||||
public function reject(WithdrawRequest $withdrawRequest, User $admin, ?string $note = null): WithdrawRequest
|
||||
{
|
||||
$this->ensurePending($withdrawRequest);
|
||||
|
||||
$withdrawRequest->update([
|
||||
'status' => WithdrawRequestStatusEnum::Rejected->value,
|
||||
'admin_note' => $note,
|
||||
'reviewed_at' => now(),
|
||||
'reviewed_by' => $admin->id,
|
||||
]);
|
||||
|
||||
return $withdrawRequest;
|
||||
}
|
||||
|
||||
protected function ensurePending(WithdrawRequest $withdrawRequest): void
|
||||
{
|
||||
if ($withdrawRequest->status !== WithdrawRequestStatusEnum::Pending) {
|
||||
throw ValidationException::withMessages(['withdraw_request' => 'این درخواست قبلا بررسی شده است.']);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user