donatello's avatar

Need guidance with building a dynamic Nested Product Menu with Pricing structure

Hello all. I'm trying to build an admin panel for cafe owners to create a dynamic product flyer/menu. Its going to be printed as a flyer for a fair.

The owner has the ability to generate categories, child levels, and products for their menu. Also to include ability of multiple types of promotion creations like full/half.

  1. I'm confused what's the best efficient way to create relationships for this,
  2. Is there any package to handle it better, especially for discount inheritance?

discounts will be split at each level. Have to use Laravel - Vue.

Please, would appreciate everyone's guidance on this.

0 likes
4 replies
Garet's avatar

In addition to what you're doing I also built my own [+][-] tree type thingy in JavaScript, with radio buttons and checkboxes to enable assigning a category to a parent, and assigning multiple products to multiple categories.

In fact it is an app I am working on now and I've spent about 3 months on it so far.

I'm afraid I am not going to write your app for you because I have my hands full doing my own :-) But maybe if I share my Category model it will give you a head start, particularly with the recursive relationships (in my app you can have an unlimited level of sub-catgories).

Migration:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('parent_id')->nullable();
            $table->string('name', 255)->nullable();
            $table->string('slug', 255)->nullable();
            $table->unsignedBigInteger('priority')->default(0);
            $table->timestamps();

            $table->unique('parent_id', 'slug');

            $table->foreign('parent_id')
                  ->references('id')
                  ->on('categories')
                  ->onDelete('cascade');
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('categories');
    }
};

And then the model with relationships:

<?php

namespace App\Models;

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

class Category extends Model
{
    /**
     * Sub categories relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasMany
     */
    public function subCategories(): hasMany
    {
        return $this->hasMany(Category::class, 'parent_id');
    }

    /**
     * All sub categories relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\hasMany
     */
    public function allSubCategories(): hasMany
    {
        return $this->hasMany(Category::class, 'parent_id')->orderBy('priority', 'asc')->with('allSubCategories');
    }

    /**
     * Parent category relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\belongsTo
     */
    public function parent(): belongsTo
    {
        return $this->belongsTo(Category::class, 'parent_id');
    }

    /**
     * Product relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function products(): BelongsToMany
    {
        return $this->belongsToMany(Product::class, 'product_category')
                    ->orderByPivot('priority')
                    ->orderBy('created_at');
    }
}
donatello's avatar

@Garet thanks but I've done this part. Its just I dont like what I did. Sorry, know that sounds vague.

martinbean's avatar

discounts will be split at each level. Have to use Laravel - Vue.

@sabira_khan Is this a job interview question or something?

donatello's avatar

@martinbean no, a team volunteer project for my university cafe. this is what the product lead / team lead, sent me for my part. all of us use laravel - vue. I have built my side of things, but I think i could make it better with some adjacency list, which is why I asked here. I watched a laravel daily video long back on country-city-shop or something. but can not understand how to fit those concepts here. I'm using hasManyThrough, hasManyDeepThrough etc but its ugly.

Please or to participate in this conversation.