Files
sam-api/database/seeders/KSS01ModelSeeder.php

574 lines
20 KiB
PHP
Raw Normal View History

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Tenant;
use App\Models\User;
use App\Models\Category;
use App\Models\Product;
use App\Models\Material;
use App\Models\Design\DesignModel;
use App\Models\Design\ModelVersion;
use App\Models\Design\ModelParameter;
use App\Models\Design\ModelFormula;
use App\Models\Design\BomConditionRule;
use App\Models\Design\BomTemplate;
use App\Models\Design\BomTemplateItem;
use Illuminate\Support\Facades\Hash;
class KSS01ModelSeeder extends Seeder
{
/**
* Run the database seeds for KSS01 specific model.
* This creates the exact KSS01 screen door model as referenced in the codebase.
*/
public function run(): void
{
// Get or create test tenant
$tenant = Tenant::firstOrCreate(
['code' => 'KSS_DEMO'],
[
'name' => 'KSS Demo Tenant',
'description' => 'Demonstration tenant for KSS01 model',
'is_active' => true
]
);
// Get or create test user
$user = User::firstOrCreate(
['email' => 'demo@kss01.com'],
[
'name' => 'KSS01 Demo User',
'password' => Hash::make('kss01demo'),
'email_verified_at' => now()
]
);
// Associate user with tenant
if (!$user->tenants()->where('tenant_id', $tenant->id)->exists()) {
$user->tenants()->attach($tenant->id, [
'is_active' => true,
'is_default' => true
]);
}
// Create screen door category
$category = Category::firstOrCreate(
[
'tenant_id' => $tenant->id,
'code' => 'SCREEN_DOORS'
],
[
'name' => 'Screen Doors',
'description' => 'Automatic screen door systems',
'is_active' => true
]
);
// Create KSS01 specific materials and products
$this->createKSS01Materials($tenant);
$this->createKSS01Products($tenant);
// Create the KSS01 model
$kss01Model = DesignModel::firstOrCreate(
[
'tenant_id' => $tenant->id,
'code' => 'KSS01'
],
[
'name' => 'KSS01 Screen Door System',
'category_id' => $category->id,
'lifecycle' => 'ACTIVE',
'description' => 'Production KSS01 automatic screen door system with parametric BOM',
'is_active' => true
]
);
// Create KSS01 parameters (matching the codebase expectations)
$this->createKSS01Parameters($tenant, $kss01Model);
// Create KSS01 formulas (matching the service expectations)
$this->createKSS01Formulas($tenant, $kss01Model);
// Create KSS01 condition rules
$this->createKSS01ConditionRules($tenant, $kss01Model);
// Create BOM template
$this->createKSS01BomTemplate($tenant, $kss01Model);
$this->command->info('KSS01 model seeded successfully!');
$this->command->info('Demo tenant: ' . $tenant->code);
$this->command->info('Demo user: ' . $user->email . ' / password: kss01demo');
}
/**
* Create KSS01 specific materials
*/
private function createKSS01Materials(Tenant $tenant): void
{
$materials = [
[
'code' => 'FABRIC_KSS01',
'name' => 'KSS01 Fabric Screen',
'description' => 'Specialized fabric for KSS01 screen door',
'unit' => 'M2',
'density' => 0.35,
'color' => 'CHARCOAL'
],
[
'code' => 'STEEL_KSS01',
'name' => 'KSS01 Steel Mesh',
'description' => 'Security steel mesh for KSS01',
'unit' => 'M2',
'density' => 2.8,
'color' => 'GRAPHITE'
],
[
'code' => 'RAIL_KSS01_GUIDE',
'name' => 'KSS01 Guide Rail',
'description' => 'Precision guide rail for KSS01 system',
'unit' => 'M',
'density' => 1.2,
'color' => 'ANODIZED'
],
[
'code' => 'CABLE_KSS01_LIFT',
'name' => 'KSS01 Lift Cable',
'description' => 'High-strength lift cable for KSS01',
'unit' => 'M',
'density' => 0.15,
'color' => 'STAINLESS'
],
[
'code' => 'SEAL_KSS01_WEATHER',
'name' => 'KSS01 Weather Seal',
'description' => 'Weather sealing strip for KSS01',
'unit' => 'M',
'density' => 0.08,
'color' => 'BLACK'
]
];
foreach ($materials as $materialData) {
Material::firstOrCreate(
[
'tenant_id' => $tenant->id,
'code' => $materialData['code']
],
array_merge($materialData, [
'is_active' => true,
'created_by' => 1
])
);
}
}
/**
* Create KSS01 specific products
*/
private function createKSS01Products(Tenant $tenant): void
{
$products = [
[
'code' => 'BRACKET_KSS01_WALL',
'name' => 'KSS01 Wall Bracket',
'description' => 'Heavy-duty wall mounting bracket for KSS01',
'unit' => 'EA',
'weight' => 0.8,
'color' => 'POWDER_COATED'
],
[
'code' => 'BRACKET_KSS01_CEILING',
'name' => 'KSS01 Ceiling Bracket',
'description' => 'Ceiling mounting bracket for KSS01',
'unit' => 'EA',
'weight' => 1.0,
'color' => 'POWDER_COATED'
],
[
'code' => 'MOTOR_KSS01_STD',
'name' => 'KSS01 Standard Motor',
'description' => 'Standard 12V motor for KSS01 (up to 4m²)',
'unit' => 'EA',
'weight' => 2.8,
'color' => 'BLACK'
],
[
'code' => 'MOTOR_KSS01_HEAVY',
'name' => 'KSS01 Heavy Duty Motor',
'description' => 'Heavy duty 24V motor for large KSS01 systems',
'unit' => 'EA',
'weight' => 4.2,
'color' => 'BLACK'
],
[
'code' => 'CONTROLLER_KSS01',
'name' => 'KSS01 Smart Controller',
'description' => 'Smart controller with app connectivity for KSS01',
'unit' => 'EA',
'weight' => 0.25,
'color' => 'WHITE'
],
[
'code' => 'CASE_KSS01_HEAD',
'name' => 'KSS01 Head Case',
'description' => 'Aluminum head case housing for KSS01',
'unit' => 'EA',
'weight' => 2.5,
'color' => 'ANODIZED'
],
[
'code' => 'BOTTOM_BAR_KSS01',
'name' => 'KSS01 Bottom Bar',
'description' => 'Weighted bottom bar for KSS01 screen',
'unit' => 'EA',
'weight' => 1.5,
'color' => 'ANODIZED'
],
[
'code' => 'PIPE_KSS01_ROLLER',
'name' => 'KSS01 Roller Pipe',
'description' => 'Precision roller pipe for KSS01 screen',
'unit' => 'EA',
'weight' => 1.0,
'color' => 'ANODIZED'
]
];
foreach ($products as $productData) {
Product::firstOrCreate(
[
'tenant_id' => $tenant->id,
'code' => $productData['code']
],
array_merge($productData, [
'is_active' => true,
'created_by' => 1
])
);
}
}
/**
* Create KSS01 parameters (matching BomResolverService expectations)
*/
private function createKSS01Parameters(Tenant $tenant, DesignModel $model): void
{
$parameters = [
[
'parameter_name' => 'W0',
'parameter_type' => 'NUMBER',
'is_required' => true,
'default_value' => '800',
'min_value' => 600,
'max_value' => 3000,
'unit' => 'mm',
'description' => 'Opening width (clear opening)',
'sort_order' => 1
],
[
'parameter_name' => 'H0',
'parameter_type' => 'NUMBER',
'is_required' => true,
'default_value' => '600',
'min_value' => 400,
'max_value' => 2500,
'unit' => 'mm',
'description' => 'Opening height (clear opening)',
'sort_order' => 2
],
[
'parameter_name' => 'screen_type',
'parameter_type' => 'SELECT',
'is_required' => true,
'default_value' => 'FABRIC',
'options' => ['FABRIC', 'STEEL'],
'description' => 'Screen material type',
'sort_order' => 3
],
[
'parameter_name' => 'install_type',
'parameter_type' => 'SELECT',
'is_required' => true,
'default_value' => 'WALL',
'options' => ['WALL', 'CEILING', 'RECESSED'],
'description' => 'Installation method',
'sort_order' => 4
],
[
'parameter_name' => 'power_source',
'parameter_type' => 'SELECT',
'is_required' => false,
'default_value' => 'AC',
'options' => ['AC', 'DC', 'BATTERY'],
'description' => 'Power source type',
'sort_order' => 5
]
];
foreach ($parameters as $paramData) {
ModelParameter::firstOrCreate(
[
'tenant_id' => $tenant->id,
'model_id' => $model->id,
'parameter_name' => $paramData['parameter_name']
],
$paramData
);
}
}
/**
* Create KSS01 formulas (matching BomResolverService::resolveKSS01)
*/
private function createKSS01Formulas(Tenant $tenant, DesignModel $model): void
{
$formulas = [
[
'formula_name' => 'W1',
'expression' => 'W0 + 100',
'description' => 'Overall width (opening + frame)',
'sort_order' => 1
],
[
'formula_name' => 'H1',
'expression' => 'H0 + 100',
'description' => 'Overall height (opening + frame)',
'sort_order' => 2
],
[
'formula_name' => 'area',
'expression' => '(W1 * H1) / 1000000',
'description' => 'Total area in square meters',
'sort_order' => 3
],
[
'formula_name' => 'weight',
'expression' => 'area * 8 + W1 / 1000 * 2.5',
'description' => 'Estimated total weight in kg',
'sort_order' => 4
],
[
'formula_name' => 'motor_load',
'expression' => 'weight * 1.5 + area * 3',
'description' => 'Motor load calculation',
'sort_order' => 5
],
[
'formula_name' => 'bracket_count',
'expression' => 'if(W1 > 1000, 3, 2)',
'description' => 'Number of brackets required',
'sort_order' => 6
],
[
'formula_name' => 'rail_length',
'expression' => '(W1 + H1) * 2 / 1000',
'description' => 'Guide rail length in meters',
'sort_order' => 7
]
];
foreach ($formulas as $formulaData) {
ModelFormula::firstOrCreate(
[
'tenant_id' => $tenant->id,
'model_id' => $model->id,
'formula_name' => $formulaData['formula_name']
],
$formulaData
);
}
}
/**
* Create KSS01 condition rules
*/
private function createKSS01ConditionRules(Tenant $tenant, DesignModel $model): void
{
$rules = [
// Screen material selection
[
'rule_name' => 'Fabric Screen Material',
'condition_expression' => 'screen_type == "FABRIC"',
'action_type' => 'INCLUDE',
'target_type' => 'MATERIAL',
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'FABRIC_KSS01')->first()->id,
'quantity_multiplier' => 'area',
'description' => 'Include fabric screen material',
'sort_order' => 1
],
[
'rule_name' => 'Steel Screen Material',
'condition_expression' => 'screen_type == "STEEL"',
'action_type' => 'INCLUDE',
'target_type' => 'MATERIAL',
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'STEEL_KSS01')->first()->id,
'quantity_multiplier' => 'area',
'description' => 'Include steel mesh material',
'sort_order' => 2
],
// Motor selection based on load
[
'rule_name' => 'Standard Motor',
'condition_expression' => 'motor_load <= 20',
'action_type' => 'INCLUDE',
'target_type' => 'PRODUCT',
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'MOTOR_KSS01_STD')->first()->id,
'quantity_multiplier' => 1,
'description' => 'Standard motor for normal loads',
'sort_order' => 3
],
[
'rule_name' => 'Heavy Duty Motor',
'condition_expression' => 'motor_load > 20',
'action_type' => 'INCLUDE',
'target_type' => 'PRODUCT',
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'MOTOR_KSS01_HEAVY')->first()->id,
'quantity_multiplier' => 1,
'description' => 'Heavy duty motor for high loads',
'sort_order' => 4
],
// Bracket selection based on installation
[
'rule_name' => 'Wall Brackets',
'condition_expression' => 'install_type == "WALL"',
'action_type' => 'INCLUDE',
'target_type' => 'PRODUCT',
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BRACKET_KSS01_WALL')->first()->id,
'quantity_multiplier' => 'bracket_count',
'description' => 'Wall mounting brackets',
'sort_order' => 5
],
[
'rule_name' => 'Ceiling Brackets',
'condition_expression' => 'install_type == "CEILING"',
'action_type' => 'INCLUDE',
'target_type' => 'PRODUCT',
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BRACKET_KSS01_CEILING')->first()->id,
'quantity_multiplier' => 'bracket_count',
'description' => 'Ceiling mounting brackets',
'sort_order' => 6
],
// Guide rail
[
'rule_name' => 'Guide Rail',
'condition_expression' => 'true', // Always include
'action_type' => 'INCLUDE',
'target_type' => 'MATERIAL',
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'RAIL_KSS01_GUIDE')->first()->id,
'quantity_multiplier' => 'rail_length',
'description' => 'Guide rail for screen movement',
'sort_order' => 7
],
// Weather sealing for large openings
[
'rule_name' => 'Weather Seal for Large Openings',
'condition_expression' => 'area > 3.0',
'action_type' => 'INCLUDE',
'target_type' => 'MATERIAL',
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'SEAL_KSS01_WEATHER')->first()->id,
'quantity_multiplier' => 'rail_length',
'description' => 'Weather sealing for large openings',
'sort_order' => 8
]
];
foreach ($rules as $ruleData) {
BomConditionRule::firstOrCreate(
[
'tenant_id' => $tenant->id,
'model_id' => $model->id,
'rule_name' => $ruleData['rule_name']
],
$ruleData
);
}
}
/**
* Create KSS01 BOM template
*/
private function createKSS01BomTemplate(Tenant $tenant, DesignModel $model): void
{
// Create model version
$modelVersion = ModelVersion::firstOrCreate(
[
'tenant_id' => $tenant->id,
'model_id' => $model->id,
'version_no' => '1.0'
],
[
'status' => 'RELEASED',
'description' => 'Initial release of KSS01',
'created_by' => 1
]
);
// Create BOM template
$bomTemplate = BomTemplate::firstOrCreate(
[
'tenant_id' => $tenant->id,
'model_version_id' => $modelVersion->id,
'name' => 'KSS01 Base BOM'
],
[
'description' => 'Base BOM template for KSS01 screen door system',
'is_active' => true,
'created_by' => 1
]
);
// Create base BOM items (always included components)
$baseItems = [
[
'ref_type' => 'PRODUCT',
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CONTROLLER_KSS01')->first()->id,
'quantity' => 1,
'waste_rate' => 0,
'order' => 1
],
[
'ref_type' => 'PRODUCT',
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CASE_KSS01_HEAD')->first()->id,
'quantity' => 1,
'waste_rate' => 0,
'order' => 2
],
[
'ref_type' => 'PRODUCT',
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BOTTOM_BAR_KSS01')->first()->id,
'quantity' => 1,
'waste_rate' => 0,
'order' => 3
],
[
'ref_type' => 'PRODUCT',
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'PIPE_KSS01_ROLLER')->first()->id,
'quantity' => 1,
'waste_rate' => 0,
'order' => 4
],
[
'ref_type' => 'MATERIAL',
'ref_id' => Material::where('tenant_id', $tenant->id)->where('code', 'CABLE_KSS01_LIFT')->first()->id,
'quantity' => 2, // Two cables
'waste_rate' => 10,
'order' => 5
]
];
foreach ($baseItems as $itemData) {
BomTemplateItem::firstOrCreate(
[
'bom_template_id' => $bomTemplate->id,
'ref_type' => $itemData['ref_type'],
'ref_id' => $itemData['ref_id'],
'order' => $itemData['order']
],
$itemData
);
}
}
}