'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 ); } } }