/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Models/Coupon.php
190 строк
4 KB
vivanenko
fix taps and others structure
27 май 2025, 18:06
27 май 2025, 18:06
8cdc7d9
Код
Авторство
О чём код?
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Factories\HasFactory; use Carbon\Carbon; /** * @property int $id * @property string $code * @property string $name * @property string|null $description * @property string $sku * @property float|null $value * @property float|null $discount * @property bool $active * @property \DateTime|null $expires_at * @property int|null $usage_limit * @property int $used_count * @property \DateTime $created_at * @property \DateTime $updated_at */ class Coupon extends Model { use HasFactory; protected $fillable = [ 'code', 'name', 'description', 'sku', 'value', 'discount', 'active', 'expires_at', 'usage_limit', 'used_count', ]; protected $casts = [ 'value' => 'decimal:2', 'discount' => 'decimal:2', 'active' => 'boolean', 'expires_at' => 'datetime', 'usage_limit' => 'integer', 'used_count' => 'integer', ]; public function usages(): HasMany { return $this->hasMany(CouponUsage::class); } /** * Check if coupon is valid */ public function isValid(): bool { return $this->active && !$this->isExpired() && !$this->isUsageLimitReached(); } /** * Check if coupon is expired */ public function isExpired(): bool { return $this->expires_at && $this->expires_at < now(); } /** * Check if usage limit is reached */ public function isUsageLimitReached(): bool { return $this->usage_limit && $this->used_count >= $this->usage_limit; } /** * Check if coupon is percentage discount */ public function isPercentageDiscount(): bool { return $this->discount !== null; } /** * Check if coupon is fixed value discount */ public function isFixedDiscount(): bool { return $this->value !== null; } /** * Calculate discount amount for given total */ public function calculateDiscount(float $total): float { if (!$this->isValid()) { return 0.0; } if ($this->isPercentageDiscount()) { return $total * ($this->discount / 100); } if ($this->isFixedDiscount()) { return min($this->value, $total); } return 0.0; } /** * Apply coupon to user and order */ public function applyToOrder(int $userId, int $orderId, float $discountAmount): CouponUsage { $this->increment('used_count'); return CouponUsage::create([ 'coupon_id' => $this->id, 'user_id' => $userId, 'order_id' => $orderId, 'discount_amount' => $discountAmount, ]); } /** * Check if user can use this coupon */ public function canBeUsedByUser(int $userId): bool { if (!$this->isValid()) { return false; } // Add additional logic here if needed (e.g., one-time use per user) return true; } /** * Scope for active coupons */ public function scopeActive($query) { return $query->where('active', true); } /** * Scope for non-expired coupons */ public function scopeNotExpired($query) { return $query->where(function ($q) { $q->whereNull('expires_at') ->orWhere('expires_at', '>', now()); }); } /** * Scope for available coupons (active and not expired) */ public function scopeAvailable($query) { return $query->active()->notExpired(); } /** * Find coupon by code */ public static function findByCode(string $code): ?self { return static::where('code', $code)->first(); } /** * Find valid coupon by code */ public static function findValidByCode(string $code): ?self { $coupon = static::findByCode($code); return $coupon && $coupon->isValid() ? $coupon : null; } }