<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Wallet extends Model
{
use HasFactory;
protected $fillable = [
'name',
'slug',
'uuid',
'description',
];
public function getRouteKeyName()
{
return 'uuid';
}
/**
* reverse relation between user->wallet
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
/**
* create relation between wallet->transaction
* wallet can be related to many transaction
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function transactions()
{
return $this->hasMany(Transaction::class);
}
/**
* get Credit for user wallet
* @return numeric
*/
public function withdraw()
{
return $this->transactions()->withdraw()->validTransactions()->sum('amount');
}
/**
* get Debit for user wallet
* @return numeric
*/
public function deposit()
{
return $this->transactions()->deposit()->validTransactions()->sum('amount');
}
/**
* get Balance for user wallet
* @return numeric
*/
public function balance()
{
return $this->deposit() - $this->withdraw();
}
/**
* check if user wallet have enough balance to create withdraw transaction
* @return boolean
*/
public function allowWithdraw($amount): bool
{
return $this->balance() >= $amount;
}
/**
* create new transaction
* @param array $data
* @return Model|null
*/
// public function createTransaction(array $data)
// {
// // if client want to withdraw and amount grater than his balance decline transaction
// if ($data['type'] === 'withdraw' && !$this->allowWithdraw($data['amount']))
// return null;
//
// // return added transaction to send it to client-app
// return $this->transactions()->create($data);
// }
/**
* @param $details
* @param Payment $payment
* @return array|mixed
*/
public function tryCreateTransaction($details, Payment $payment)
{
if ($details['transaction_type'] === 'withdraw')
return $this->createWithdrawTransaction($payment, $details['amount']);
else if ($details['transaction_type'] === 'deposit')
return $this->createDepositTransaction($payment, $details['amount']);
return ['status' => false, 'msg' => 'Unknown Error!'];
}
/**
* @param Payment $payment
* @param $amount
* @return mixed
*/
public function createWithdrawTransaction(Payment $payment, $amount)
{
if (!$this->allowWithdraw($amount)) {
return ['status' => false, 'msg' => 'your balance less than transaction amount.'];
}
if ($amount > $payment->max_withdrawal || $amount < $payment->min_withdrawal) {
return ['status' => false, 'msg' =>
"transaction decline, payment method you using limit is: max: {$payment->max_withdrawal}, min: {$payment->min_withdrawal}"];
}
return $this->createTransaction('withdraw', $amount, $payment->id);
}
/**
* @param Payment $payment
* @param $amount
* @return mixed
*/
public function createDepositTransaction(Payment $payment, $amount)
{
if ($amount > $payment->max_deposit || $amount < $payment->min_deposit) {
return ['status' => false, 'msg' =>
"transaction decline, payment method you using limit is: max: {$payment->max_deposit}, min: {$payment->min_deposit}"];
}
return $this->createTransaction('deposit', $amount, $payment->id);
}
/**
* @param $type
* @param $amount
* @param $payment
* @return mixed
*/
private function createTransaction($type, $amount, $payment)
{
return $this->transactions()->create([
'amount' => $amount,
'uuid' => Str::uuid(),
'payment_id' => $payment,
'type' => $type
]);
}
}
|