feat(db): implement wallet and discount code systems

Add database migrations and Eloquent models to support user wallets,
transaction history, and discount code functionality. Includes a
one-to-one relationship between User and Wallet.
This commit is contained in:
Kazem Alghasi 2026-08-05 17:35:58 +03:30
parent 67754f3e08
commit 6aa18f76a8
7 changed files with 173 additions and 0 deletions

View File

@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DiscountCode extends Model
{
protected $fillable = [
'code', 'type', 'value', 'min_order_amount',
'usage_limit', 'used_count', 'expires_at', 'is_active'
];
protected $casts = [
'expires_at' => 'datetime',
'is_active' => 'boolean',
];
}

View File

@ -5,6 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Models\Wallet;
class User extends Authenticatable
{
@ -54,4 +55,10 @@ class User extends Authenticatable
{
return $this->role === \App\Enums\UserRole::Customer;
}
//کیف پول
public function wallet()
{
return $this->hasOne(Wallet::class);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use App\Models\WalletTransaction;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Wallet extends Model
{
protected $fillable = ['user_id', 'balance'];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function transactions(): HasMany
{
return $this->hasMany(WalletTransaction::class);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Wallet;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class WalletTransaction extends Model
{
protected $fillable = ['wallet_id', 'amount', 'type', 'description', 'transactionable_type', 'transactionable_id'];
public function wallet(): BelongsTo
{
return $this->belongsTo(Wallet::class);
}
public function transactionable(): MorphTo
{
return $this->morphTo();
}
}

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wallets', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->unique()->constrained()->cascadeOnDelete();
$table->decimal('balance', 15, 2)->default(0); // موجودی به ریال یا تومان
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wallets');
}
};

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wallet_transactions', function (Blueprint $table) {
$table->id();
$table->foreignId('wallet_id')->constrained()->cascadeOnDelete();
$table->decimal('amount', 15, 2); // مثبت برای واریز، منفی برای برداشت
$table->enum('type', ['deposit', 'withdraw', 'order_payment']); // نوع تراکنش
$table->string('description')->nullable();
$table->string('transactionable_type');
$table->unsignedBigInteger('transactionable_id');
$table->index(['transactionable_type', 'transactionable_id'], 'wallet_txn_morph_index');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wallet_transactions');
}
};

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('discount_codes', function (Blueprint $table) {
$table->id();
$table->string('code')->unique();
$table->enum('type', ['fixed', 'percent']); // مبلغ ثابت یا درصد
$table->decimal('value', 15, 2);
$table->decimal('min_order_amount', 15, 2)->default(0);
$table->integer('usage_limit')->nullable();
$table->integer('used_count')->default(0);
$table->timestamp('expires_at')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('discount_codes');
}
};