Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
3 changes: 3 additions & 0 deletions database/seeders/CatalogueSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class CatalogueSeeder extends Seeder
{
public function run(): void
{
$this->call(MeasureUnitSeeder::class);
$this->call(TaxClassSeeder::class);
$this->call(PriceListSeeder::class);
$this->call(CategorySeeder::class);
$this->call(ProductTypeSeeder::class);
$this->call(GroupSeeder::class);
Expand Down
33 changes: 33 additions & 0 deletions database/seeders/MeasureUnitSeeder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Eclipse\Catalogue\Seeders;

use Eclipse\Catalogue\Models\MeasureUnit;
use Illuminate\Database\Seeder;

class MeasureUnitSeeder extends Seeder
{
public function run(): void
{
// Create pcs / kos as default
$pcs = MeasureUnit::updateOrCreate(
['name' => 'pcs / kos'],
['is_default' => true]
);

// Ensure only one default remains true
MeasureUnit::where('id', '!=', $pcs->id)->update(['is_default' => false]);

// Create set / set
MeasureUnit::updateOrCreate(
['name' => 'set / set'],
['is_default' => false]
);

// Create pair / par
MeasureUnit::updateOrCreate(
['name' => 'pair / par'],
['is_default' => false]
);
}
}
97 changes: 70 additions & 27 deletions database/seeders/PriceListSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,85 @@ class PriceListSeeder extends Seeder
*/
public function run(): void
{
// Ensure we have at least one currency
if (Currency::count() === 0) {
// Ensure currencies exist
if (! Currency::where('id', 'EUR')->exists()) {
Currency::create(['id' => 'EUR', 'name' => 'Euro', 'is_active' => true]);
}
if (! Currency::where('id', 'USD')->exists()) {
Currency::create(['id' => 'USD', 'name' => 'US Dollar', 'is_active' => true]);
}

// Create price lists using factory
$priceLists = PriceList::factory()
->count(3)
->create();
// Desired price lists
$definitions = [
[
'name' => 'Wholesale / Veleprodajni cenik',
'code' => 'VPC',
'currency_id' => 'EUR',
'tax_included' => false,
'is_default' => false,
'is_default_purchase' => false,
],
[
'name' => 'Retail / Maloprodajni cenik',
'code' => 'MPC',
'currency_id' => 'EUR',
'tax_included' => true,
'is_default' => true, // default selling
'is_default_purchase' => false,
],
[
'name' => 'Purchase / Nabavni cenik',
'code' => 'NC',
'currency_id' => 'USD',
'tax_included' => false,
'is_default' => false,
'is_default_purchase' => true, // default purchase
],
];

// Create price list data for each price list
foreach ($priceLists as $index => $priceList) {
// Create data for all tenants if tenancy is enabled
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantModel = config('eclipse-catalogue.tenancy.model');
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantModel = config('eclipse-catalogue.tenancy.model');
$tenants = collect();
if ($tenantFK && $tenantModel && class_exists($tenantModel)) {
$tenants = $tenantModel::all();
}

if ($tenantFK && $tenantModel && class_exists($tenantModel)) {
$tenants = $tenantModel::all();
foreach ($definitions as $def) {
$priceList = PriceList::updateOrCreate(
['code' => $def['code']],
[
'name' => $def['name'],
'currency_id' => $def['currency_id'],
'tax_included' => $def['tax_included'],
]
);

// Ensure per-tenant data
if ($tenants->isNotEmpty()) {
foreach ($tenants as $tenant) {
PriceListData::factory()->create([
'price_list_id' => $priceList->id,
$tenantFK => $tenant->id,
'is_active' => true,
'is_default' => $index === 0, // First price list is default selling
'is_default_purchase' => false,
]);
PriceListData::updateOrCreate(
[
'price_list_id' => $priceList->id,
$tenantFK => $tenant->id,
],
[
'is_active' => true,
'is_default' => $def['is_default'],
'is_default_purchase' => $def['is_default_purchase'],
]
);
}
} else {
// No tenancy - create single record
PriceListData::factory()->create([
'price_list_id' => $priceList->id,
'is_active' => true,
'is_default' => $index === 0, // First price list is default selling
'is_default_purchase' => false,
]);
PriceListData::updateOrCreate(
[
'price_list_id' => $priceList->id,
],
[
'is_active' => true,
'is_default' => $def['is_default'],
'is_default_purchase' => $def['is_default_purchase'],
]
);
}
}
}
Expand Down
93 changes: 93 additions & 0 deletions database/seeders/ProductSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

use Eclipse\Catalogue\Models\Category;
use Eclipse\Catalogue\Models\Group;
use Eclipse\Catalogue\Models\PriceList;
use Eclipse\Catalogue\Models\Product;
use Eclipse\Catalogue\Models\Product\Price as ProductPrice;
use Eclipse\Catalogue\Models\ProductData;
use Eclipse\Catalogue\Models\ProductStatus;
use Eclipse\Catalogue\Models\ProductType;
use Eclipse\Catalogue\Models\Property;
use Eclipse\Catalogue\Models\PropertyValue;
use Exception;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
Expand Down Expand Up @@ -38,6 +42,9 @@ public function run(): void
$products = Product::query()->latest('id')->take(100)->get();

foreach ($products as $index => $product) {
// Assign product prices for all price lists
$this->assignRandomPrices($product);

if ($tenantFK && $tenantModel && class_exists($tenantModel)) {
$tenants = $tenantModel::all();
foreach ($tenants as $tenant) {
Expand All @@ -58,6 +65,9 @@ public function run(): void
// Assign random product status for this tenant
$this->assignRandomProductStatus($productData, $tenant->id);

// Attach random unit of measure (list property) and custom property values
$this->attachRandomUnitAndCustomProps($product);

// Get groups for this specific tenant
$tenantGroups = Group::where($tenantFK, $tenant->id)->get();
$groupsToAdd = $this->determineGroupsForProduct($index, $tenantGroups);
Expand All @@ -79,6 +89,9 @@ public function run(): void
// Assign random product status for non-tenant scenario
$this->assignRandomProductStatus($productData, null);

// Attach random unit of measure (list property) and custom property values
$this->attachRandomUnitAndCustomProps($product);

// For non-tenant scenarios, use all groups
$groups = Group::all();
$groupsToAdd = $this->determineGroupsForProduct($index, $groups);
Expand Down Expand Up @@ -198,4 +211,84 @@ private function assignRandomProductStatus(ProductData $productData, ?int $tenan
}
}
}

/**
* Create random current prices for all price lists for a product.
*/
private function assignRandomPrices(Product $product): void
{
$priceLists = PriceList::all();
if ($priceLists->isEmpty()) {
return;
}

foreach ($priceLists as $pl) {
// Generate a base retail price between 10 and 500 (EUR/USD agnostic)
$baseRetail = rand(1000, 50000) / 100; // 10.00 - 500.00

if ($pl->code === 'MPC') {
$priceValue = $baseRetail;
} elseif ($pl->code === 'VPC') {
// Wholesale discount 10% - 30%
$discountFactor = rand(70, 90) / 100; // 0.70 - 0.90
$priceValue = round($baseRetail * $discountFactor, 2);
} elseif ($pl->code === 'NC') {
// Purchase price: slightly lower than wholesale or independent band
$priceValue = round(max(1, $baseRetail * rand(60, 80) / 100), 2);
} else {
$priceValue = $baseRetail;
}

ProductPrice::updateOrCreate(
[
'product_id' => $product->id,
'price_list_id' => $pl->id,
'valid_from' => now()->toDateString(),
],
[
'price' => $priceValue,
'tax_included' => (bool) $pl->tax_included,
]
);
}
}

/**
* Attach unit of measure (list property) and custom property values.
*/
private function attachRandomUnitAndCustomProps(Product $product): void
{
// Unit of measure via list property
$uomProperty = Property::where('code', 'unit_of_measure')->first();
if ($uomProperty) {
$values = PropertyValue::where('property_id', $uomProperty->id)->get();
if ($values->isNotEmpty()) {
$product->propertyValues()->syncWithoutDetaching([$values->random()->id]);
}
}

// Custom properties
$materialDetails = Property::where('code', 'material_details')->first();
if ($materialDetails) {
$product->setCustomPropertyValue($materialDetails, [
'en' => 'Made from premium materials',
'sl' => 'Izdelano iz kakovostnih materialov',
]);
}

$skuNotes = Property::where('code', 'sku_notes')->first();
if ($skuNotes) {
$product->setCustomPropertyValue($skuNotes, 'Handle with care');
}

$releaseDate = Property::where('code', 'release_date')->first();
if ($releaseDate) {
$product->setCustomPropertyValue($releaseDate, now()->subDays(rand(0, 365))->toDateString());
}

$dimensions = Property::where('code', 'dimensions')->first();
if ($dimensions) {
$product->setCustomPropertyValue($dimensions, rand(10, 200) / 10); // 1.0 - 20.0
}
}
}
Loading