Certainly! Since you cannot change the database tables, the best approach is to define the concept of a "Set" (like "AYZ") as configuration or code (an array or collection in Laravel), and handle the logic for selling a set within your application layer. When a set is sold, you will expand it into its component items and store them as regular SoldInventoryItems, just as if each item had been sold individually, but using the "Set" as an abstraction to make the seller/buyer's life easier.
Here’s how you can implement this:
1. Define Your Sets (Programming-Level Only)
For example, you can define your set structures in a config file, or in code:
// config/item_sets.php
return [
'AYZ' => [
'name' => 'AYZ',
'items' => [
// inventory_item_id => quantity_per_set
1 => 2, // A
2 => 3, // Y
3 => 5, // Z
],
'set_price' => 100,
],
// More sets...
];
2. Selling a Set (Application Logic Example)
When a seller sells a set, you expand the set into its items, multiply the quantities by number of sets, and create SoldInventoryItems for each:
use Illuminate\Support\Facades\DB;
function sellSet($soldInventoryId, $setKey, $numberOfSets)
{
$set = config("item_sets.$setKey");
if (!$set) {
throw new Exception("Set not found");
}
$totalSetPrice = $set['set_price'] * $numberOfSets;
// Calculate total quantity per item and allocate price per item
$items = $set['items'];
$totalItemsQty = collect($items)->map(fn($qty) => $qty * $numberOfSets);
// Optionally split the price per item, here simply dividing equally:
$totalItemsCount = $totalItemsQty->sum();
// Or distribute proportionally to item count
$unitPricePerItem = $totalSetPrice / $totalItemsCount;
DB::transaction(function () use (
$soldInventoryId, $items, $numberOfSets, $unitPricePerItem, $set
) {
foreach ($items as $inventory_item_id => $qtyPerSet) {
$quantity = $qtyPerSet * $numberOfSets;
// Retrieve InventoryInStore for the relevant InventoryItem
$inventoryInStore = \App\Models\InventoryInStore::where('inventory_item_id', $inventory_item_id)
->firstOrFail();
\App\Models\SoldInventoryItems::create([
'sold_inventory_id' => $soldInventoryId,
'inventory_in_store_id' => $inventoryInStore->id,
'quantity' => $quantity,
'unit_price' => $unitPricePerItem,
'sub_total' => $quantity * $unitPricePerItem,
]);
}
});
}
3. Usage (For Example in Your Livewire Component)
// Example: Buyer wants to buy 2 AYZ sets and the SoldInventory ID is 5
sellSet(5, 'AYZ', 2);
Notes:
- This solution leaves your database schema unchanged, but allows the application to deal with Sets as higher-order groups of items.
- You can place the set definitions in a config file, or even in the database (if you add new tables later), but for now, config or code is fastest for production systems.
- Pricing per item inside the set is split equally. Adjust the price distribution logic as necessary for your needs.
Summary:
Define your sets in config/code, expand to items in your app, and process sales as if individual items were sold, but powered by the "set" logic. This avoids any database changes and works with your existing SoldInventory/SoldInventoryItems models.