'boolean', 'is_unlimited' => 'boolean', 'published_at' => 'date', 'gallery' => 'array', ]; /** * Relationship: Product belongs to a Category */ public function category() { return $this->belongsTo(ProductCategories::class, 'product_categories_id'); } /** * Relationship: Product has many OS versions (pivot table: os_product) */ public function osVersions() { return $this->belongsToMany(Os::class, 'os_product', 'product_id', 'os_id') ->withTimestamps(); } /** * Relationship: Product has many Control Panels (for Hosting) */ public function controlPanels() { return $this->belongsToMany(ControlPanel::class, 'product_control_panel') ->withPivot(['price_modifier', 'is_default']) ->withTimestamps(); } /** * Relationship: Product has many pricings */ public function pricings() { return $this->hasMany(ProductPricings::class, 'product_id'); } /** * Relationship: Product has many order items */ public function orderItems() { return $this->hasMany(OrderItem::class, 'product_id'); } /** * Relationship: Product has many orders through order items */ public function orders() { return $this->hasManyThrough(Order::class, OrderItem::class, 'product_id', 'id', 'id', 'order_id'); } /** * Legacy: Many-to-many categories (if still needed) */ public function categories() { return $this->belongsToMany(ProductCategories::class, 'product_product_category', 'product_id', 'product_category_id'); } /** * Relationship: Product has many addons (through product type) * Addons are linked via type_id in product_addon table */ public function addons() { // Assuming product_addon has type_id field that links to product type return $this->hasMany(Addon::class, 'type_id', 'product_type') ->orderBy('sort_order'); } /** * Get monthly pricing (or first available pricing) */ public function getMonthlyPricingAttribute() { return $this->pricings() ->where('is_active', 1) ->where('billing_cycle', 'monthly') ->first() ?? $this->pricings()->where('is_active', 1)->orderBy('price')->first(); } /** * Get display price (sale price if available, otherwise regular price) */ public function getPriceAttribute() { $pricing = $this->monthlyPricing; return $pricing ? $pricing->price : 0; } public function getPriceSaleAttribute() { $pricing = $this->monthlyPricing; return $pricing ? $pricing->price_sale : null; } }