Files
2026-02-06 20:52:59 +07:00

175 lines
4.9 KiB
PHP

<?php
namespace App\Http\Services;
use App\Models\ProductPricings;
use App\Repositories\Admin\Product\ProductRepositoryInterface;
use Illuminate\Support\Str;
class ProductService
{
protected ProductRepositoryInterface $repository;
public function __construct(
ProductRepositoryInterface $repository
) {
$this->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;
}
}