main
This commit is contained in:
Executable
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "rooyesh/wallet",
|
||||
"description": "wallet module for source transaction system , balance management system ...",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Rooyesh\\Wallet\\": "src/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "yousef amini",
|
||||
"email": "yo3ef.amini@gmail.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
|
||||
}
|
||||
}
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "rooyesh/wallet",
|
||||
"description": "wallet module for source transaction system , balance management system ...",
|
||||
"type": "composer-plugin",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Rooyesh\\Wallet\\": "src/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "yousef amini",
|
||||
"email": "yo3ef.amini@gmail.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
|
||||
}
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet;
|
||||
|
||||
class Wallet {}
|
||||
Executable
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class LastTransactionValidateFailed extends Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class NotEnoughCashBalance extends Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class NotEnoughCreditBalance extends Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class WalletValidateFailed extends Exception
|
||||
{
|
||||
private $wallet_id = null;
|
||||
|
||||
public function __construct($wallet, $user = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->wallet_id = $wallet->id;
|
||||
}
|
||||
|
||||
public function context()
|
||||
{
|
||||
return [' ' => $this->wallet_id];
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class WalletServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
$this->loadMigrationsFrom(__DIR__ . "/migrations");
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\interfaces;
|
||||
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Rooyesh\Wallet\models\TransactionMeta;
|
||||
use Rooyesh\Wallet\models\Wallet;
|
||||
use Rooyesh\Wallet\models\Transaction;
|
||||
use Rooyesh\Wallet\Exceptions;
|
||||
use \Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
class TransactionInterface
|
||||
{
|
||||
|
||||
private $_inp;
|
||||
private $_type;
|
||||
private $wallet_interface;
|
||||
private $transaction;
|
||||
|
||||
function __construct($wallet_interface = null, $_inp = null, $_type = null,$deposit_gold = false,$deposit_cash=false, $gold_block = 0,$meta = [])
|
||||
|
||||
{
|
||||
$this->transaction = TransactionInterface::apply_transaction($wallet_interface, $_inp, $_type,$deposit_gold ,$deposit_cash,$gold_block,$meta);
|
||||
}
|
||||
|
||||
static function validate_last_transaction($wallet_id)
|
||||
{
|
||||
// $last_transaction = Transaction::where('wallet', '=', $wallet_id)->orderBy('created_at', 'DESC')->first();
|
||||
// if ($last_transaction and $last_transaction->hash !== TransactionInterface::generate_hash($last_transaction)) {
|
||||
// throw new Exceptions\LastTransactionValidateFailed();
|
||||
// }
|
||||
}
|
||||
|
||||
private static function generate_hash($transaction)
|
||||
{
|
||||
$last_transaction_hash = '';
|
||||
$last_user_transaction = Transaction::where('wallet', '=', $transaction->wallet)->orderBy('created_at', 'DESC');
|
||||
if ($last_user_transaction->count() and $last_user_transaction->first() != $transaction) {
|
||||
$last_transaction_hash = $last_user_transaction->first()->hash;
|
||||
}
|
||||
return hash('sha256',
|
||||
hash('sha256', $transaction->gold) .
|
||||
hash('sha256', $transaction->cash) .
|
||||
hash('sha256', $transaction->wallet) .
|
||||
"yhoenszeaf" . $last_transaction_hash
|
||||
);
|
||||
}
|
||||
|
||||
private static function set_hash($transaction)
|
||||
{
|
||||
$transaction->hash = TransactionInterface::generate_hash($transaction);
|
||||
$transaction->save();
|
||||
}
|
||||
|
||||
public static function apply_transaction($wallet_interface, $_inp, $_type,$deposit_gold,$deposit_cash,$gold_block, $meta = [])
|
||||
{
|
||||
$wallet = $wallet_interface->wallet;
|
||||
TransactionInterface::validate_last_transaction($wallet->id);
|
||||
#-------------Check Balance --------
|
||||
if (!$deposit_gold) {
|
||||
// if ($_type === 1 && $wallet->cash < $_inp['value']) {
|
||||
// throw new Exceptions\NotEnoughCashBalance();
|
||||
//
|
||||
// }
|
||||
if ($_type === 2 && $wallet->gold < $_inp['gold']) {
|
||||
throw new UnprocessableEntityHttpException('مقدار وارد شده کمتر از موجودی شماست');
|
||||
|
||||
}
|
||||
}
|
||||
// $_inp['value'] = abs($_inp['value']) * ($deposit ? 1 : -1);
|
||||
if (isset($_inp['gold'])){
|
||||
$_inp['gold'] = abs($_inp['gold']) * ($deposit_gold ? 1 : -1);
|
||||
$wallet->gold += $_inp['gold'];
|
||||
$_inp['balance_gold'] = $wallet->gold;
|
||||
}
|
||||
if (isset($_inp['cash'])){
|
||||
$_inp['cash'] = abs($_inp['cash']) * ($deposit_cash ? 1 : -1);
|
||||
$wallet->cash += $_inp['cash'];
|
||||
$_inp['balance_cash'] = $wallet->cash;
|
||||
}
|
||||
if($gold_block != 0){
|
||||
$wallet->gold_block += $gold_block;
|
||||
}
|
||||
$_inp['wallet'] = $wallet->id;
|
||||
$_inp['type'] = $_type;
|
||||
// $_inp['transaction_type'] = $_type;
|
||||
$_inp['customer_id'] = $wallet->owner;
|
||||
// $_inp['balance'] = $wallet->cash + $_inp['cash'];
|
||||
$transaction_validate_rules = [
|
||||
'wallet' => 'required',
|
||||
'type' => 'required',
|
||||
'expire_at' => 'date',
|
||||
'cash' => 'integer',
|
||||
'note' => 'string',
|
||||
'balance' => 'integer',
|
||||
];
|
||||
$transaction_validator = Validator::make($_inp, $transaction_validate_rules);
|
||||
if ($transaction_validator->failed()) {
|
||||
throw ValidationException::withMessages($transaction_validator->errors()->all());
|
||||
}
|
||||
$transaction = Transaction::create($_inp);
|
||||
$transaction->save();
|
||||
TransactionInterface::set_hash($transaction);
|
||||
$meta['transaction'] = $transaction->id;
|
||||
$transaction_metas = TransactionMeta::create($meta);
|
||||
|
||||
// if ($_inp['type'] == 1) {
|
||||
// $wallet->cash += $_inp['value'];
|
||||
// } elseif ($_inp['type'] == 2) {
|
||||
// $wallet->gold += $_inp['value'];
|
||||
// }
|
||||
$wallet->save();
|
||||
$wallet_interface->set_hash();
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\interfaces;
|
||||
|
||||
use Rooyesh\Wallet\models\Wallet;
|
||||
use Rooyesh\Wallet\models\Transaction;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
|
||||
class WalletInterface
|
||||
{
|
||||
public $wallet = null;
|
||||
public $owner_id = null;
|
||||
public $owner_type = null;
|
||||
public $fund_id = null;
|
||||
public $product_id = null;
|
||||
|
||||
function __construct($owner_id, $owner_type, $fund_id=null,$product_id=null)
|
||||
{
|
||||
$this->owner_id = $owner_id;
|
||||
$this->owner_type = $owner_type;
|
||||
|
||||
if (wallet::where([
|
||||
['owner', '=', $owner_id],
|
||||
['owner_type', '=', $owner_type],
|
||||
['fund_id', '=', $fund_id],
|
||||
['product_id', '=', $product_id],
|
||||
])->count()) {
|
||||
$this->wallet = wallet::where([
|
||||
['owner', '=', $owner_id],
|
||||
['owner_type', '=', $owner_type],
|
||||
['fund_id', '=', $fund_id],
|
||||
['product_id', '=', $product_id],
|
||||
])->first();
|
||||
$this->validate();
|
||||
} else {
|
||||
$this->wallet = Wallet::create([
|
||||
'owner' => $owner_id,
|
||||
'owner_type' => $owner_type,
|
||||
'gold' => 0,
|
||||
'cash' => 0,
|
||||
'fund_id'=>$fund_id,
|
||||
'product_id'=>$product_id
|
||||
]);
|
||||
$this->set_hash();
|
||||
}
|
||||
}
|
||||
|
||||
public function validate(): bool
|
||||
{
|
||||
|
||||
// if ($this->wallet->hash !== $this->generate_hash()) {
|
||||
// throw new UnprocessableEntityHttpException('امکان شارز این کیف پول وجود ندارد');
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
private function generate_hash(): string
|
||||
{
|
||||
$last_transaction = Transaction::where('wallet', '=', $this->wallet->id)->orderBy('created_at', 'DESC')->first();
|
||||
$last_transaction_hash = $last_transaction ? hash('sha256', $last_transaction->hash) : '';
|
||||
return hash('sha256', hash('sha256', $this->wallet->gold) .
|
||||
hash('sha256', $this->wallet->cash) . hash('sha256', $this->wallet->owner) . $last_transaction_hash . "yhoenszeaf");
|
||||
}
|
||||
|
||||
public function set_hash(): bool
|
||||
{
|
||||
$this->wallet->hash = $this->generate_hash();
|
||||
$this->wallet->save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateWalletMoudleTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('wallets', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$ownerTypes = [
|
||||
1 => "user",
|
||||
2 => "shop",
|
||||
];
|
||||
$table->enum('owner_type', array_keys($ownerTypes))->default(1);
|
||||
$table->timestamps();
|
||||
$table->bigInteger('owner');
|
||||
$table->bigInteger('cash');
|
||||
$table->string('hash', 128)->nullable(true);
|
||||
$table->float('gold');
|
||||
$table->bigInteger('fund_id')->nullable();
|
||||
|
||||
});
|
||||
|
||||
Schema::create('transactions', function (Blueprint $table) {
|
||||
$transactionTypes = [
|
||||
1 => "cash",
|
||||
2 => "gold",
|
||||
3 => "expire",
|
||||
];
|
||||
$table->id();
|
||||
$table->bigInteger('wallet', false, true);
|
||||
$table->enum('transaction_type', array_keys($transactionTypes))->default(1);
|
||||
$table->timestamps();
|
||||
$table->bigInteger('cash')->nullable();
|
||||
$table->float('gold')->default(0);
|
||||
$table->dateTime('expire_at')->nullable(true);
|
||||
$table->string('hash', 128)->nullable(true);
|
||||
$table->text('note')->nullable(true);
|
||||
$table->bigInteger('customer_id')->nullable()->unsigned();
|
||||
$table->integer('type')->nullable()->unsigned();
|
||||
$table->bigInteger('fund_id')->nullable();
|
||||
$table->timestamp('start_at')->nullable();
|
||||
$table->timestamp('end_at')->nullable();
|
||||
|
||||
});
|
||||
|
||||
Schema::create('transaction_metas', function (Blueprint $table) {
|
||||
$table->bigInteger('transaction', false, true);
|
||||
$table->bigInteger('order_id')->nullable()->unsigned();
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\models;
|
||||
|
||||
use App\Models\Selector;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
||||
class Transaction extends Model
|
||||
{
|
||||
use HasFactory,Selector;
|
||||
protected $guarded=['hash'];
|
||||
protected $casts = [
|
||||
'active'=>'boolean',
|
||||
'number'=>'float',
|
||||
];
|
||||
static $TYPES = [
|
||||
1 => 'خرید طلا',
|
||||
2 => 'فروش طلا',
|
||||
3 => 'واریز ریالی',
|
||||
7 => 'واریز طلایی',
|
||||
4 => 'برداشت ریالی',
|
||||
5 => 'واریز',
|
||||
6 => 'برداشت',
|
||||
8 => ' پاداش بابت معرفی',
|
||||
9 => 'سود زیر مجموعه',
|
||||
];
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Customer')->select(['id','name']);
|
||||
}
|
||||
|
||||
|
||||
public function wallet()
|
||||
{
|
||||
return $this->belongsTo(Wallet::class, 'wallet', 'id'); // 'wallet' is the foreign key in transactions table
|
||||
}
|
||||
public function fund()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Fund','fund_id')->select(['id','title']);
|
||||
}
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Product','product_id')->select(['id','title','group_type']);
|
||||
}
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Order','order_id');
|
||||
}
|
||||
public function withdraw()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Withdraw','withdraw_id');
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TransactionMeta extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $guarded=[];
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Rooyesh\Wallet\models;
|
||||
|
||||
use App\Models\Selector;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Wallet extends Model
|
||||
{
|
||||
protected $guarded=['hash'];
|
||||
use Selector;
|
||||
|
||||
use HasFactory;
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Customer','owner')->select(['id','name']);
|
||||
}
|
||||
public function fund()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Fund','fund_id')->select(['id','title']);
|
||||
}
|
||||
public function Product()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Product','product_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user