Files
portal-api/app/Http/Livewire/Cart/SummaryAddons.php
T
2025-07-24 16:18:27 +07:00

134 lines
4.1 KiB
PHP

<?php
namespace App\Http\Livewire\Cart;
use App\Models\Addon;
use Livewire\Component;
class SummaryAddons extends Component
{
public $product;
public $addons = [];
public $index;
public $months = 1;
public $cachedTotalPrice = null;
public function mount($product, $index = null, $months = 1)
{
$this->product = $product;
$this->months = $months;
// Lấy tất cả addon từ database
$addonsFromDb = Addon::all()->toArray();
// Chuyển đổi dữ liệu addon từ database sang định dạng phù hợp với component
$this->addons = collect($addonsFromDb)->map(function ($addon) {
return [
'id' => $addon['id'],
'name' => $addon['name'],
'price' => $addon['price'],
'min' => $addon['min'],
'max' => $addon['max'],
'step' => $addon['step'],
'prefix' => $addon['prefix'],
'type_id' => $addon['type_id'],
'qty' => 0, // Khởi tạo số lượng ban đầu là 0
];
})->toArray();
$this->index = $index;
}
public function increment($key)
{
if ($this->addons[$key]['qty'] < ($this->addons[$key]['max'] ?? PHP_INT_MAX)) {
$this->addons[$key]['qty'] += ($this->addons[$key]['step'] ?? 1);
}
$this->calculateTotal();
$this->dispatch('addonUpdated', addons: $this->addons);
}
public function decrement($key)
{
if ($this->addons[$key]['qty'] > ($this->addons[$key]['min'] ?? 0)) {
$this->addons[$key]['qty'] -= ($this->addons[$key]['step'] ?? 1);
}
$this->calculateTotal();
$this->dispatch('addonUpdated', addons: $this->addons);
}
// Triggered when input fields are updated directly
public function updated($name, $value)
{
// Check if the updated property is related to addon quantity
if (strpos($name, 'addons.') !== false && strpos($name, '.qty') !== false) {
$parts = explode('.', $name);
$key = $parts[1] ?? null;
if ($key !== null && isset($this->addons[$key])) {
// Ensure quantity is within bounds
$min = $this->addons[$key]['min'] ?? 0;
$max = $this->addons[$key]['max'] ?? PHP_INT_MAX;
$step = $this->addons[$key]['step'] ?? 1;
// Round to the nearest step
$this->addons[$key]['qty'] = round($value / $step) * $step;
// Apply min/max constraints
$this->addons[$key]['qty'] = max($min, $this->addons[$key]['qty']);
$this->addons[$key]['qty'] = min($max, $this->addons[$key]['qty']);
// Ensure total is recalculated immediately
$this->calculateTotal();
// Notify listeners that addon has been updated
$this->dispatch('addonUpdated', addons: $this->addons);
}
}
}
public function hydrate()
{
// This method is called on every Livewire request
// Perfect place to make sure our computed properties are up-to-date
$this->calculateTotal();
}
protected function calculateTotal()
{
// Lấy giá sản phẩm ưu tiên sale nếu có
$basePrice = $this->product->price_sale ?: $this->product->price;
// Nhân với số tháng
$total = $basePrice * $this->months;
foreach ($this->addons as $addon) {
$total += $addon['qty'] * $addon['price'] * $this->months;
}
$this->cachedTotalPrice = $total;
return $total;
}
public function getTotalAddonPriceProperty()
{
return collect($this->addons)->sum(function ($addon) {
return $addon['qty'] * ($addon['price'] ?? 0) * $this->months;
});
}
public function getTotalPriceProperty()
{
// Use cached value if available, otherwise calculate
return $this->cachedTotalPrice ?? $this->calculateTotal();
}
public function render()
{
return view('livewire.cart.summary-addons');
}
}