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