update
This commit is contained in:
@@ -2,117 +2,143 @@
|
||||
|
||||
namespace App\Http\Services;
|
||||
|
||||
use App\Enums\Product\ProductTypeEnums;
|
||||
use App\Enums\Status;
|
||||
use App\Models\ProductPricings;
|
||||
use App\Repositories\Admin\Product\ProductRepositoryInterface;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Exception;
|
||||
|
||||
class ProductService
|
||||
{
|
||||
protected ProductRepositoryInterface $repository;
|
||||
|
||||
public function __construct(
|
||||
protected ProductRepositoryInterface $productRepository
|
||||
) {}
|
||||
ProductRepositoryInterface $repository
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
public function store(array $data)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$typeId = (int) ($data['type_id'] ?? 0);
|
||||
$productType = $this->mapTypeIdToEnum($typeId);
|
||||
|
||||
if (!$productType) {
|
||||
throw new Exception('Invalid Product Type');
|
||||
}
|
||||
// Prepare product data
|
||||
$productData = $this->prepareData($data);
|
||||
|
||||
$prepareData = [
|
||||
'uuid' => (string) Str::uuid(),
|
||||
'name' => $data['name'],
|
||||
'slug' => Str::slug($data['name']),
|
||||
'product_type' => $productType->value,
|
||||
'is_active' => isset($data['status']) && (int)$data['status'] === Status::ACTIVE->value,
|
||||
|
||||
'price' => $data['price'] ?? 0,
|
||||
'price_sale' => $data['price_sale'] ?? null,
|
||||
'description' => $data['description'] ?? null,
|
||||
|
||||
// VPS Columns
|
||||
'cpu' => $data['cpu'] ?? null,
|
||||
'ram' => $data['ram'] ?? null,
|
||||
'disk' => $data['disk'] ?? null,
|
||||
'bandwidth' => $data['bandwidth'] ?? null,
|
||||
'gpu' => $data['gpu'] ?? null, // if added later
|
||||
|
||||
// Extra fields
|
||||
'sort_order' => $data['sort_order'] ?? 0,
|
||||
'billing_cycle' => $data['billing_cycle'] ?? 'monthly',
|
||||
];
|
||||
// Create product
|
||||
$product = $this->repository->create($productData);
|
||||
|
||||
$product = $this->productRepository->create($prepareData);
|
||||
|
||||
DB::commit();
|
||||
return $product;
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
throw $e;
|
||||
// Sync OS versions if provided
|
||||
if (!empty($data['os_ids'])) {
|
||||
$product->osVersions()->sync($data['os_ids']);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$prepareData = [];
|
||||
|
||||
if (isset($data['name'])) {
|
||||
$prepareData['name'] = $data['name'];
|
||||
$prepareData['slug'] = Str::slug($data['name']);
|
||||
}
|
||||
|
||||
if (isset($data['status'])) {
|
||||
$prepareData['is_active'] = (int)$data['status'] === Status::ACTIVE->value;
|
||||
}
|
||||
|
||||
// Map other fields that overlap with fillable
|
||||
$fillable = ['price', 'price_sale', 'billing_cycle', 'cpu', 'ram', 'gpu', 'disk', 'bandwidth', 'sort_order', 'description'];
|
||||
foreach ($fillable as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$prepareData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
// Prepare product data
|
||||
$productData = $this->prepareData($data, false);
|
||||
|
||||
$result = $this->productRepository->update($id, $prepareData);
|
||||
|
||||
DB::commit();
|
||||
return $result;
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
throw $e;
|
||||
// Update product
|
||||
$result = $this->repository->update($id, $productData);
|
||||
|
||||
// Get the product for relationships
|
||||
$product = $this->repository->find($id);
|
||||
|
||||
// Sync OS versions if provided
|
||||
if (isset($data['os_ids'])) {
|
||||
$product->osVersions()->sync($data['os_ids']);
|
||||
}
|
||||
|
||||
// Save pricing cycles if provided
|
||||
if (!empty($data['pricing'])) {
|
||||
$this->savePricings($product, $data['pricing'], $data['currency'] ?? 'USD');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function delete(int $id)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$this->productRepository->delete($id);
|
||||
DB::commit();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
throw $e;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function mapTypeIdToEnum(int $typeId): ?ProductTypeEnums
|
||||
|
||||
/**
|
||||
* Prepare data for create/update
|
||||
*/
|
||||
private function prepareData(array $data, bool $isCreate = true): array
|
||||
{
|
||||
return match ($typeId) {
|
||||
1 => ProductTypeEnums::ADDON,
|
||||
2 => ProductTypeEnums::DOMAIN,
|
||||
3 => ProductTypeEnums::HOSTING,
|
||||
4 => ProductTypeEnums::VPS,
|
||||
default => null
|
||||
};
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user