Files
radicall/app/Services/Wallet/WithdrawRequestService.php

98 lines
3.2 KiB
PHP

<?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' => 'این درخواست قبلا بررسی شده است.']);
}
}
}