repository = $repository; } public function store(array $data) { // Prepare product data $productData = $this->prepareData($data); // Create product $product = $this->repository->create($productData); // Sync OS versions if provided (for VPS) if (!empty($data['os_ids'])) { $product->osVersions()->sync($data['os_ids']); } // Sync Control Panels if provided (for Hosting) if (!empty($data['control_panel_ids'])) { $this->saveControlPanels($product, $data); } // Save pricing cycles if provided if (!empty($data['pricing'])) { $this->savePricings($product, $data['pricing'], $data['currency'] ?? 'USD'); } return $product; } public function update(int $id, array $data) { // Prepare product data $productData = $this->prepareData($data, false); // Update product $result = $this->repository->update($id, $productData); // Get the product for relationships $product = $this->repository->find($id); // Sync OS versions if provided (for VPS) if (isset($data['os_ids'])) { $product->osVersions()->sync($data['os_ids']); } // Sync Control Panels if provided (for Hosting) if (isset($data['control_panel_ids'])) { $this->saveControlPanels($product, $data); } // Save pricing cycles if provided if (!empty($data['pricing'])) { $this->savePricings($product, $data['pricing'], $data['currency'] ?? 'USD'); } return $result; } public function delete(int $id) { return $this->repository->delete($id); } /** * Save pricing cycles for product */ private function savePricings($product, array $pricingData, string $currency): void { foreach ($pricingData as $cycle => $pricing) { // Only save if enabled and has price if (!empty($pricing['enabled']) && isset($pricing['price'])) { ProductPricings::updateOrCreate( [ 'product_id' => $product->id, 'billing_cycle' => $cycle, ], [ 'price' => $pricing['price'] ?? 0, 'price_sale' => $pricing['price_sale'] ?? null, 'currency' => $currency, 'is_active' => true, ] ); } else { // Remove pricing if not enabled ProductPricings::where('product_id', $product->id) ->where('billing_cycle', $cycle) ->delete(); } } } /** * Save Control Panels for product (for Hosting) */ private function saveControlPanels($product, array $data): void { $syncData = []; foreach ($data['control_panel_ids'] as $panelId) { $priceModifier = $data['control_panel_price_modifiers'][$panelId] ?? 0; $isDefault = isset($data['control_panel_default']) && $data['control_panel_default'] == $panelId; $syncData[$panelId] = [ 'price_modifier' => $priceModifier, 'is_default' => $isDefault, ]; } $product->controlPanels()->sync($syncData); } /** * Prepare data for create/update */ private function prepareData(array $data, bool $isCreate = true): array { $prepared = []; // Generate UUID and slug only on create if ($isCreate) { $prepared['uuid'] = (string) Str::uuid(); } // Name and slug if (isset($data['name'])) { $prepared['name'] = $data['name']; $prepared['slug'] = Str::slug($data['name']); } // Direct mappable fields $fillableFields = [ 'short_description', 'description', 'setup_fee', 'trial_days', 'cpu', 'ram', 'gpu', 'disk', 'bandwidth', 'stock', 'is_unlimited', 'is_active', 'sort_order', 'product_type', 'product_categories_id', 'published_at', ]; foreach ($fillableFields as $field) { if (array_key_exists($field, $data)) { $prepared[$field] = $data[$field]; } } return $prepared; } }