Hacker News new | ask | show | jobs
by junebuggerz 303 days ago
I know you don't know Laravel, but this is what I changed and told me I did a good job now, with some minor tweaks that need to be done like Laravel Form Requests for form validation

<?php

namespace App\Services;

use App\Models\Product; use App\Models\Category; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\Collection;

class ProductService {

    public function store(array $data, string $category_id): Product {

        $product_to_save = new Product([
            'name' => $data['name'],
            'slug' => $data['slug'],
            'description' => $data['description'],
            'price' => $data['price'],
            'sku' => $data['sku'],
            'stock_quantity' => $data['stock_quantity'],
        ]);

        $category = Category::findOrFail($category_id);
        $product = $category->products()->save($product_to_save);
        
        return $product;

    }

    public function getProductsByCategory(string $category_name): Collection {

        $category = Category::where('name', $category_name)->firstOrFail();
        return $category->products()->with('category')->get();

    }

    public function detail(string $id): Product {

        $product = Product::findOrFail($id);
        
        return $product;

    }

    public function index(): Collection {

        $product = Product::all();

        if ($product->isEmpty()) {
            throw (new ModelNotFoundException)->setModel(Product::class);
        }

        return $product;

    }

    public function delete(string $id){

        $product = Product::findOrFail($id);
        
        $product->delete();

        return $product;

    }

    public function checkStock(string $id): Boolean {
        $in_stock = null;

        $product = Product::findOfFail($id);
        $product_stock = $product->stock_quantity;

        if($product_stock > 0){
            $in_stock = true;
        }

        if($product_stock == 0){
            $in_stock = false;
        }

        return $in_stock;

    }

    public function updateProductStock(string $id, int $amount): Boolean {

        $product = Product::findOrFail($id);

        if($amount < 0) {

            return false;

        } else {

            $product->stock_quantity = $amount;
            $product->save();

            return true;

        }

    }

    public function applyDiscount(string $id, float $percentage): Boolean {

        $product = Product::findOrFail($id);

        if ($percentage <= 0 || $percentage > 100) {

            return false;

        }

        $discount_amount = $product->price * ($percentage / 100);
        $new_price = $product->price - $discount_amount;

        $product->price = max(0, $new_price);
        $product->save();

        return true;
    }

    public function makeProductFeatured(string $id): Boolean {

        $product = Product::findOrFail($id);

        $product->is_featured = true;
        $product->save();

        return true;

    }

    public function getAllFeaturedProducts(): Collection {

        $featured_products = Product::where('is_featured', true)->with('category')->get();

        return $featured_products;

    }
}

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request; use App\Services\ProductService; use Illuminate\Http\JsonResponse;

class ProductController extends Controller { //

    public function __construct(ProductService $productService) {
        
        $this->productService = $productService;
    
    }
    
    public function store(Request $request): JsonResponse {

        $category_id = $request->category_id;

        $validated_data = $request->validate([
            'name' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required|string|max:255',
            'price' => 'required|numeric',
            'sku' => 'required|string|max:255',
            'stock_quantity' => 'required|numeric',
        ]);

        //$path = $request->file('image')->store('images', 'public');
        
        $product = $this->productService->store($validated_data, $category_id);
            return response()->json([
                'product' => $product,
            ]);
    }

    public function getProductsByCategory(string $category_name): JsonResponse {

        $product = $this->productService->getProductsByCategory($category_name);
        return response()->json([
            'products' => $product,
        ]);

    }

    public function index(): JsonResponse {

        $product = $this->productService->index();

        return response()->json([
            'products' => $product,
        ]);

    }

    public function detail(string $id): JsonResponse {

        $product = $this->productService->detail($id);
        return response()->json([
            'product' => $product,
        ]);

    }

    public function delete(string $id): JsonResponse {

        $product = $this->productService->delete($id);
        return response()->json([
            'product' => $product,
        ]);

    }
}

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany;

class Product extends Model { // use SoftDeletes;

    protected $fillable = [
        'category_id',
        'name',
        'slug',
        'description',
        'short_description',
        'price',
        'compare_at_price',
        'sku',
        'stock_quantity',
        'is_featured',
        'is_active',
        'weight',
        'dimensions',
    ];

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function product_images(): HasMany
    {
        return $this->hasMany(ProductImage::class);
    }

    public function reviews(): HasMany
    {
        return $this->hasMany(Review::class);
    }

    public function productskus(): HasMany
    {
        return $this->hasMany(ProductSku::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(Tag::class);
    }
    
}

This compared to the code from code review stack overflow is a major changer I guess... Like I said everything you said and more lined up pretty clearly, of course there is always room for making the code better, but it's a start I guess...