/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Models/Order.php
215 строк
6 KB
vivanenko
purchase demo
28 май 2025, 15:54
28 май 2025, 15:54
b6d38b6
Код
Авторство
О чём код?
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Factories\HasFactory; /** * @property int $id * @property int $user_id * @property string $status_code * @property float $subtotal_amount * @property float $discount_amount * @property float $tax_amount * @property float $shipping_amount * @property float $total_amount * @property string $currency * @property string|null $payment_gateway * @property array|null $metadata * @property \DateTime $created_at * @property \DateTime $updated_at */ class Order extends Model { use HasFactory; protected $fillable = [ 'user_id', 'status_code', 'subtotal_amount', 'discount_amount', 'tax_amount', 'shipping_amount', 'total_amount', 'currency', 'payment_gateway', 'payment_details', 'metadata', ]; protected $casts = [ 'user_id' => 'integer', 'status_code' => 'string', 'subtotal_amount' => 'decimal:2', 'discount_amount' => 'decimal:2', 'tax_amount' => 'decimal:2', 'shipping_amount' => 'decimal:2', 'total_amount' => 'decimal:2', 'payment_details' => 'array', 'metadata' => 'array', 'status' => 'array', ]; public function user(): BelongsTo { return $this->belongsTo(User::class); } public function status(): BelongsTo { return $this->belongsTo(OrderStatus::class, 'status_code', 'code'); } public function transactions(): HasMany { return $this->hasMany(Transaction::class); } public function items(): HasMany { return $this->hasMany(CartItem::class); } public function cartItems(): HasMany { return $this->hasMany(CartItem::class, 'order_id'); } public function couponUsages(): HasMany { return $this->hasMany(CouponUsage::class); } // Методы для работы со статусами public function isPending(): bool { return $this->status_code === OrderStatus::PENDING; } public function isProcessing(): bool { return $this->status_code === OrderStatus::PROCESSING; } public function isPaid(): bool { return $this->status_code === OrderStatus::PAID; } public function isFailed(): bool { return $this->status_code === OrderStatus::FAILED; } public function isCancelled(): bool { return $this->status_code === OrderStatus::CANCELLED; } public function isRefunded(): bool { return $this->status_code === OrderStatus::REFUNDED; } public function isFinal(): bool { return $this->status?->isFinal() ?? false; } // Методы для изменения статуса public function markAsPending(): self { $this->status_code = OrderStatus::PENDING; return $this; } public function markAsProcessing(): self { $this->status_code = OrderStatus::PROCESSING; return $this; } public function markAsPaid(): self { $this->status_code = OrderStatus::PAID; return $this; } public function markAsFailed(): self { $this->status_code = OrderStatus::FAILED; return $this; } public function markAsCancelled(): self { $this->status_code = OrderStatus::CANCELLED; return $this; } public function markAsRefunded(): self { $this->status_code = OrderStatus::REFUNDED; return $this; } // Получение последней транзакции public function getLatestTransaction(): ?Transaction { return $this->transactions()->latest()->first(); } // Получение общей суммы заказа public function getTotalAmount(): float { return $this->total_amount; } // Пересчет суммы заказа на основе элементов public function recalculateAmounts(): self { $subtotal = $this->items->sum(function (CartItem $item) { return $item->getSubtotal(); }); $quantityDiscount = $this->items->sum(function (CartItem $item) { return $item->getQuantityDiscount(); }); $couponDiscount = $this->couponUsages->sum('discount_amount'); $this->subtotal_amount = $subtotal; $this->discount_amount = $quantityDiscount + $couponDiscount; $this->total_amount = $subtotal - $this->discount_amount + $this->tax_amount + $this->shipping_amount; return $this; } // Создание заказа из корзины public static function createFromCart(Cart $cart, array $orderData = []): self { $totals = $cart->getTotalWithDiscounts(); $order = static::create(array_merge([ 'user_id' => $cart->user_id, 'status_code' => OrderStatus::PENDING, 'subtotal_amount' => $totals['subtotal'], 'discount_amount' => $totals['quantity_discount'], 'tax_amount' => 0, 'shipping_amount' => 0, 'total_amount' => $totals['total'], 'currency' => 'RUB', ], $orderData)); // Перемещаем элементы корзины в заказ foreach ($cart->items as $item) { $item->moveToOrder($order->id); } return $order; } }