HEX
Server: LiteSpeed
System: Linux sv4.hami.host 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64
User: armgroup (1008)
PHP: 8.2.32
Disabled: show_source, system, shell_exec, passthru, exec, popen, proc_open, mail, socket_create, socket_create_listen, socket_create_pair, link, dl, openlog, syslog, stream_socket_server, curl_multi_init
Upload Files
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);
    }
}