File: //home/armgroup/libs/app/Models/Discount.php
<?php
namespace App\Models;
use App\Enums\DiscountableType;
use App\Enums\DiscountType;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class Discount extends Model
{
use HasFactory, LogsActivity;
protected $guarded = ['id'];
protected $casts = [
'discountable_items' => 'array',
];
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logUnguarded()
->setDescriptionForEvent(fn (string $eventName
) => "کد تخفیف ({$this->title}) ".eventNameTranslate($eventName));
}
public function user()
{
return $this->belongsTo(User::class)->withDefault();
}
public function users()
{
return $this->belongsToMany(User::class)->using(DiscountUser::class);
}
public function codes()
{
return $this->hasMany(DiscountUser::class);
}
public function getMessageAttribute()
{
$text = $this->title."\n";
$text .= $this->type == DiscountType::PERCENT ? to_persian_numbers($this->amount).' درصد تخفیف' : to_persian_numbers(number_format($this->amount)).' تومان تخفیف';
if (is_null($this->discountable_items)) {
$text .= ' برای تمام محصولات';
} else {
$text .= ' '.DiscountableType::fromValue($this->discountable_type)->description;
$items = $this->discountable_type::whereIn('id', $this->discountable_items)->select('name')->get();
$last = array_key_last($items->toArray());
foreach ($items as $key => $item) {
$text .= ' '.$item->name;
if ($key !== $last) {
$text .= ' و';
}
}
}
if ($this->minimum_order_price) {
$price = to_persian_numbers(number_format($this->minimum_order_price));
$text .= " (حداقل سفارش: {$price} تومان)";
}
$text .= "\n کد تخفیف: {$this->code}";
$text .= "\n قابل استفاده از ".to_persian_numbers(jdate($this->start_date)->format('Y/m/d')).' تا '.to_persian_numbers(jdate($this->end_date)->format('Y/m/d'));
$text .= $this->usage ? ' # '.to_persian_numbers($this->usage).' بار مصرف' : ' # بدون محدودیت در دفعات استفاده';
return $text;
}
public function isValid(int $price, User $user): string
{
if ($this->start_date > Carbon::now()) {
return 'زمان استفاده از این کد تخفیف نرسیده';
}
if ($this->end_date < Carbon::now()) {
return 'انقضای این کد تخفیف تمام شده';
}
if ($this->exceedMinOrderPriceLimitation($price)) {
return 'شما باید حداقل به میزان '.number_format($this->minimum_order_price).' تومان از محصولات شامل کد تخفیف خرید کنید.';
}
if ($this->is_general) {
$discountUser = DiscountUser::firstOrCreate(['discount_id' => $this->id, 'user_id' => $user->id]);
} else {
$discountUser = DiscountUser::where('discount_id', $this->id)->where('user_id', $user->id)->first();
}
if (! $discountUser) {
return 'تنها کاربری که کد تخفیف دریافت کرده باشد قادر به استفاده از آن است';
}
if ($this->usage && ($this->usage - $discountUser->usage <= 0)) {
return 'کد تخفیف قبلا استفاده شده است';
}
return 'OK';
}
public function calculateDiscountPrice($products_total_price)
{
return $this->type == DiscountType::PERCENT ? round($products_total_price * $this->amount / 100) : ($this->amount > $products_total_price ? $products_total_price : $this->amount);
}
public function exceedMinOrderPriceLimitation($price): bool
{
return $this->minimum_order_price && ($this->minimum_order_price > $price);
}
}