yonka's avatar

sell items as a set of items ?

I build a database, after finished and start working, there is a problem arise from the seller, the seller is selling items, so the seller required to sell an items as a set. A set contains specific items with specific Quantities that are known for instance: a set has a name like AYZ and it has to have quantities like 1,2,..etc so if the buyer wants to buy AYZ 2sets, the buyer knows how many items each AYZ will have. So instead of mentioning all these items simply the buyer will say "I need AYZ 2sets" and that has even specific price not all item price. the seller will tell each AYZ price like: $100x2sets = $200total. but the seller knows that $100 will divide to all other items that a set will contain. So I want to be able to make AYZ set and specify how many items it will have with specific quantities like : AYZ One set contains:

  1. A = 2pcs

  2. Y = 3pcs

  3. Z = 5pcs so if the buyer wants AYZ 2set, it will multiply by 2 and will be like this: AYZ Two set contains:

  4. A = 2pcs*2 = 4pcs

  5. Y = 3pcs*2 = 6pcs

  6. Z = 5pcs*2 = 10pcs This is my database I am using right now, the seller is able to sell each item as an individual, SO I want to able to add this functionality to my database. I have these tables

  7. SoldInventory Table,

class SoldInventory extends Model
{
    use HasFactory, CreatedUpdatedBy, softDeletes;

    protected $fillable = ['customer_id','store_id','date_of_sale','tracking_no','reference','reference_no','description','user_id'];

    public function soldInventoryItems()
    {
        return $this->hasMany(SoldInventoryItems::class);
    }

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function salesInvoice()
    {
        return $this->hasOne(SalesInvoice::class);
    }

    public function store()
    {
        return $this->belongsTo(Store::class);
    }
}
  1. SoldInventoryItems Table,
class SoldInventoryItems extends Model
{
    use HasFactory, CreatedUpdatedBy, softDeletes;

    protected $fillable = ['inventory_in_store_id','quantity','unit_price','sub_total'];


    public function soldInventory()
    {
        return $this->belongsTo(SoldInventory::class);
    }

    public function inventoryInStore() : BelongsTo
    {
        return $this->belongsTo(InventoryInStore::class);
    }
}```
3. InventoryInStore Table.

class InventoryInStore extends Model { use HasFactory, CreatedUpdatedBy, softDeletes;

protected $fillable = ['inventory_item_id','quantity','store_id'];

public function store()
{
    return $this->belongsTo(Store::class);
}

public function inventoryItem()
{
    return $this->belongsTo(InventoryItem::class);
}

public function soldInventoryItems()
{
    return $this->hasMany(SoldInventoryItems::class);
}

}

4. InventoryItem Table

class InventoryItem extends Model { use HasFactory, CreatedUpdatedBy, softDeletes;

public function item()
{
    return $this->belongsTo(Item::class);
}

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


public function inventoryInStores()
{
    return $this->hasMany(InventoryInStore::class);
}

}

I am using laravel and livewire.
0 likes
1 reply
LaryAI's avatar
Level 58

To achieve selling items as a set (bundle) in your Laravel application, you'll need to extend your database structure. The core idea here is:

  • Define "Set" Products: A set (like "AYZ") is itself a product, with its own name and price.
  • Link Items and Quantities to Sets: Each set contains several items, each with specific quantities.
  • Handling Sale: When a customer buys the set, you store that, but internally, you also know which items and how many of each are being sold.

1. Database Structure Additions

a) Create product_sets Table

This table will represent a "set" of items.

php artisan make:model ProductSet -m

Migration example:

Schema::create('product_sets', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->decimal('price', 10, 2); // price for each set
    $table->timestamps();
});

b) Create Pivot Table: product_set_items

This connects a set to items and specifies quantities.

Schema::create('product_set_items', function (Blueprint $table) {
    $table->id();
    $table->foreignId('product_set_id')->constrained()->onDelete('cascade');
    $table->foreignId('inventory_item_id')->constrained()->onDelete('cascade');
    $table->integer('quantity'); // pieces per set
    $table->timestamps();
});

2. Model Relationships

ProductSet.php

class ProductSet extends Model
{
    protected $fillable = ['name', 'price'];

    public function items()
    {
        return $this->belongsToMany(InventoryItem::class, 'product_set_items')
                    ->withPivot('quantity');
    }
}

InventoryItem.php

Add this:

public function productSets()
{
    return $this->belongsToMany(ProductSet::class, 'product_set_items')
                ->withPivot('quantity');
}

3. Creating and Selling a Set

  • When creating a set, the admin chooses which items it contains and their default quantities.
  • When a customer buys a set, you:
    • Add a record to sold_inventory_items for the set as one line item (with its specific set price).
    • Optionally, for stock management, deduct the correct multiplied quantities of each component item from your inventory.

Example: Calculating Item Quantities for Multiple Sets

Suppose a customer orders 2 AYZ sets, and AYZ is defined as:

  • A: 2pcs
  • Y: 3pcs
  • Z: 5pcs

Code sample to get the per-item quantities for any number of sets:

$set = ProductSet::with('items')->where('name', 'AYZ')->first();
$numberOfSets = 2;

// Build a list of items and total quantities needed
foreach ($set->items as $item) {
    $itemName = $item->item->name; // assuming you have $item->item relationship
    $totalQty = $item->pivot->quantity * $numberOfSets;
    echo "{$itemName} = {$item->pivot->quantity}pcs * {$numberOfSets} = {$totalQty}pcs\n";
}

4. Selling a Set (Livewire/Controller Example)

When a buyer orders AYZ 2 sets:

  1. Add a line to sold_inventory_items with inventory_in_store_id set to the set (or a dummy/set record), quantity as 2, unit_price as $100, sub_total as $200.
  2. For inventory management, decrement each component item in your store's inventory:
foreach ($set->items as $item) {
    $totalQty = $item->pivot->quantity * $numberOfSets;

    // Find inventory in store and reduce quantity
    $invInStore = InventoryInStore::where('inventory_item_id', $item->id)
                                  ->where('store_id', $storeId)
                                  ->first();

    if ($invInStore) {
        $invInStore->quantity -= $totalQty;
        $invInStore->save();
    }
}

5. Optional: Reporting/Breakdown

Store only the set in sold_inventory_items, but when displaying an invoice breakdown, retrieve the set components and multiply by sets sold to show actual item distribution.


Summary

  • Add product_sets and product_set_items (pivot) tables.
  • Relate sets to items, with quantities.
  • When selling a set, sell by set price and adjust inventory by breaking down to actual component usage.
  • All logic can be wrapped into service classes or inside your Livewire actions.

If you want concrete migration or Livewire sample code, let me know!

Please or to participate in this conversation.