Files
portal-api/app/Http/Controllers/admin/product/ProductController.php
T

175 lines
5.7 KiB
PHP

<?php
namespace App\Http\Controllers\admin\product;
use App\Enums\Product\ProductTypeEnums;
use App\Http\Controllers\Controller;
use App\Http\Requests\Product\ProductRequest;
use App\Http\Services\ProductService;
use App\Repositories\Group\GroupRepositoryInterface;
use App\Repositories\Admin\Product\ProductRepositoryInterface;
use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables;
use Exception;
class ProductController extends Controller
{
public function __construct(
public GroupRepositoryInterface $groupRepository,
public ProductRepositoryInterface $productRepository,
public ProductService $productService
) {
parent::__construct();
}
public function index(Request $request)
{
$products = $this->productRepository->filter(
[
'page' => $request->get('page') ?? 1
]
);
$title = "List All Product";
return view('administrator.pages.product.index', compact('title', 'products'));
}
public function create(Request $request)
{
$step = $request->get('step') ?? 1;
$title = 'Add new product';
// Fetch Product Categories (Roots only, children via relation)
$group = \App\Models\ProductCategories::where('is_active', \App\Enums\Status::ACTIVE->value)->whereNull('parent_id')->get();
$type = null;
// Fetch OS versions with their group for the OS selector component
$osVersions = \App\Models\Os::with('osGroup')->where('status', 1)->get();
// Fetch Control Panels for Hosting products
$controlPanels = \App\Models\ControlPanel::active()->ordered()->get();
if ($step === 1) {
return view("administrator.pages.product.create", compact('group', 'type', 'title', 'osVersions', 'controlPanels'));
}
if (!$request->has(['step', 'type'])) {
return back()->withErrors('Missing step or type');
}
$type_id = (int) $request->type;
$product_name = $request->name;
$view = "administrator.pages.product.create";
$data = compact('type_id', 'title', 'group', 'type', 'product_name', 'osOptions');
return view($view, $data);
}
public function store(ProductRequest $request)
{
try {
$this->productService->store($request->validated());
return redirect()->route('products.index')->with('success', 'Add new product success');
} catch (Exception $e) {
return back()->withErrors($e->getMessage())->withInput();
}
}
public function edit(Request $request, $id)
{
$product = $this->productRepository->find($id);
if (!$product) {
return back()->withErrors("Can't find product.");
}
// Load relationships
$product->load(['pricings', 'osVersions', 'category']);
$title = 'Edit product: ' . $product->name;
$group = \App\Models\ProductCategories::where('is_active', \App\Enums\Status::ACTIVE->value)->whereNull('parent_id')->get();
$type = null;
// Fetch OS versions for select
$osVersions = \App\Models\Os::with('osGroup')->where('status', 1)->get();
$view = "administrator.pages.product.edit";
// Fetch Control Panels for Hosting products
$controlPanels = \App\Models\ControlPanel::active()->ordered()->get();
$data = compact('product', 'title', 'group', 'type', 'osVersions', 'controlPanels');
return view($view, $data);
}
public function update(ProductRequest $request, $id)
{
try {
$this->productService->update((int) $id, $request->validated());
return redirect()->route('products.index')->with('success', 'Update product success');
} catch (Exception $e) {
return back()->withErrors($e->getMessage())->withInput();
}
}
public function destroy(Request $request, $id)
{
try {
$this->productService->delete((int) $id);
return redirect()->route('products.index')->with('success', 'Deleted successfully');
} catch (Exception $e) {
return back()->withErrors($e->getMessage());
}
}
public function datatable(Request $request)
{
$query = $this->productRepository->filter(
$request->all(),
['category'],
[],
['*'],
true
);
return DataTables::eloquent($query)
->addColumn('category_name', function ($d) {
return $d->category?->name ?? '-';
})
->addColumn('product_type_label', function ($d) {
$type = ProductTypeEnums::tryFrom($d->product_type);
return $type ? $type->label() : '-';
})
->addColumn('specs', function ($d) {
return view('administrator.pages.product.datatable.specs', ['row' => $d])->render();
})
->addColumn('status', function ($d) {
return view('administrator.pages.product.datatable.status', ['row' => $d])->render();
})
->addColumn(
'action',
function ($d) {
return view('administrator.pages.product.datatable.action', ['row' => $d])->render();
}
)
->rawColumns(['specs', 'status', 'action'])
->make(true);
}
private function mapEnumToTypeId(?ProductTypeEnums $enum): int
{
return match ($enum) {
ProductTypeEnums::ADDON => 1,
ProductTypeEnums::DOMAIN => 2,
ProductTypeEnums::HOSTING => 3,
ProductTypeEnums::VPS => 4,
default => 0
};
}
}