- DB 연결: 로컬/Docker 환경 오버라이딩 설정 (.env) - 테넌트 위젯: redirect 버그 수정 (TenantSelectorWidget) - 통계 위젯: 사용자/제품/자재/주문 카드 추가 (StatsOverviewWidget) - 리소스 한국어화: Product, Material 모델 레이블 추가 - 대시보드: 위젯 등록 및 캐시 최적화 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
821 lines
29 KiB
PHP
821 lines
29 KiB
PHP
<?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 ParametricBomSeeder extends Seeder
|
|
{
|
|
/**
|
|
* Run the database seeds for parametric BOM testing.
|
|
*/
|
|
public function run(): void
|
|
{
|
|
// Create test tenant
|
|
$tenant = Tenant::firstOrCreate(
|
|
['code' => 'TEST_TENANT'],
|
|
[
|
|
'name' => 'Test Tenant for Parametric BOM',
|
|
'description' => 'Tenant for testing parametric BOM system',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
// Create test user
|
|
$user = User::firstOrCreate(
|
|
['email' => 'test@parametric-bom.com'],
|
|
[
|
|
'name' => 'Parametric BOM Test User',
|
|
'password' => Hash::make('password'),
|
|
'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 categories
|
|
$screenCategory = Category::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => 'SCREEN_SYSTEMS'
|
|
],
|
|
[
|
|
'name' => 'Screen Door Systems',
|
|
'description' => 'Automatic screen door systems',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
$materialsCategory = Category::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => 'MATERIALS'
|
|
],
|
|
[
|
|
'name' => 'Raw Materials',
|
|
'description' => 'Raw materials and components',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
$componentsCategory = Category::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => 'COMPONENTS'
|
|
],
|
|
[
|
|
'name' => 'Components',
|
|
'description' => 'Manufactured components and parts',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
// Create test products
|
|
$this->createTestProducts($tenant, $componentsCategory);
|
|
|
|
// Create test materials
|
|
$this->createTestMaterials($tenant, $materialsCategory);
|
|
|
|
// Create design models
|
|
$this->createDesignModels($tenant, $screenCategory);
|
|
|
|
$this->command->info('Parametric BOM test data seeded successfully!');
|
|
}
|
|
|
|
/**
|
|
* Create test products
|
|
*/
|
|
private function createTestProducts(Tenant $tenant, Category $category): void
|
|
{
|
|
$products = [
|
|
[
|
|
'code' => 'BRACKET_WALL_STD',
|
|
'name' => 'Standard Wall Bracket',
|
|
'description' => 'Standard mounting bracket for wall installation',
|
|
'unit' => 'EA',
|
|
'weight' => 0.5,
|
|
'color' => 'WHITE'
|
|
],
|
|
[
|
|
'code' => 'BRACKET_CEILING_STD',
|
|
'name' => 'Standard Ceiling Bracket',
|
|
'description' => 'Standard mounting bracket for ceiling installation',
|
|
'unit' => 'EA',
|
|
'weight' => 0.7,
|
|
'color' => 'WHITE'
|
|
],
|
|
[
|
|
'code' => 'MOTOR_DC_12V',
|
|
'name' => 'DC Motor 12V',
|
|
'description' => 'DC motor for screen operation, 12V',
|
|
'unit' => 'EA',
|
|
'weight' => 2.5,
|
|
'color' => 'BLACK'
|
|
],
|
|
[
|
|
'code' => 'MOTOR_DC_24V',
|
|
'name' => 'DC Motor 24V',
|
|
'description' => 'DC motor for screen operation, 24V (for larger screens)',
|
|
'unit' => 'EA',
|
|
'weight' => 3.2,
|
|
'color' => 'BLACK'
|
|
],
|
|
[
|
|
'code' => 'CONTROLLER_BASIC',
|
|
'name' => 'Basic Controller',
|
|
'description' => 'Basic remote controller for screen operation',
|
|
'unit' => 'EA',
|
|
'weight' => 0.2,
|
|
'color' => 'WHITE'
|
|
],
|
|
[
|
|
'code' => 'CONTROLLER_SMART',
|
|
'name' => 'Smart Controller',
|
|
'description' => 'Smart controller with app connectivity',
|
|
'unit' => 'EA',
|
|
'weight' => 0.3,
|
|
'color' => 'BLACK'
|
|
],
|
|
[
|
|
'code' => 'CASE_ALUMINUM',
|
|
'name' => 'Aluminum Case',
|
|
'description' => 'Aluminum housing case for screen mechanism',
|
|
'unit' => 'EA',
|
|
'weight' => 1.8,
|
|
'color' => 'SILVER'
|
|
],
|
|
[
|
|
'code' => 'CASE_PLASTIC',
|
|
'name' => 'Plastic Case',
|
|
'description' => 'Plastic housing case for screen mechanism',
|
|
'unit' => 'EA',
|
|
'weight' => 1.2,
|
|
'color' => 'WHITE'
|
|
]
|
|
];
|
|
|
|
foreach ($products as $productData) {
|
|
Product::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => $productData['code']
|
|
],
|
|
array_merge($productData, [
|
|
'category_id' => $category->id,
|
|
'is_active' => true,
|
|
'created_by' => 1
|
|
])
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create test materials
|
|
*/
|
|
private function createTestMaterials(Tenant $tenant, Category $category): void
|
|
{
|
|
$materials = [
|
|
[
|
|
'code' => 'FABRIC_SCREEN_STD',
|
|
'name' => 'Standard Screen Fabric',
|
|
'description' => 'Standard fabric material for screen doors',
|
|
'unit' => 'M2',
|
|
'density' => 0.3, // kg/m2
|
|
'color' => 'GRAY'
|
|
],
|
|
[
|
|
'code' => 'FABRIC_SCREEN_PREMIUM',
|
|
'name' => 'Premium Screen Fabric',
|
|
'description' => 'Premium fabric material with enhanced durability',
|
|
'unit' => 'M2',
|
|
'density' => 0.4,
|
|
'color' => 'CHARCOAL'
|
|
],
|
|
[
|
|
'code' => 'STEEL_MESH_FINE',
|
|
'name' => 'Fine Steel Mesh',
|
|
'description' => 'Fine steel mesh for security screens',
|
|
'unit' => 'M2',
|
|
'density' => 2.5,
|
|
'color' => 'SILVER'
|
|
],
|
|
[
|
|
'code' => 'STEEL_MESH_COARSE',
|
|
'name' => 'Coarse Steel Mesh',
|
|
'description' => 'Coarse steel mesh for ventilation screens',
|
|
'unit' => 'M2',
|
|
'density' => 2.0,
|
|
'color' => 'SILVER'
|
|
],
|
|
[
|
|
'code' => 'RAIL_GUIDE_ALU',
|
|
'name' => 'Aluminum Guide Rail',
|
|
'description' => 'Aluminum guide rail for screen movement',
|
|
'unit' => 'M',
|
|
'density' => 0.8, // kg/m
|
|
'color' => 'SILVER'
|
|
],
|
|
[
|
|
'code' => 'RAIL_GUIDE_PLASTIC',
|
|
'name' => 'Plastic Guide Rail',
|
|
'description' => 'Plastic guide rail for lightweight screens',
|
|
'unit' => 'M',
|
|
'density' => 0.3,
|
|
'color' => 'WHITE'
|
|
],
|
|
[
|
|
'code' => 'CABLE_STEEL',
|
|
'name' => 'Steel Cable',
|
|
'description' => 'Steel cable for screen lifting mechanism',
|
|
'unit' => 'M',
|
|
'density' => 0.1,
|
|
'color' => 'SILVER'
|
|
],
|
|
[
|
|
'code' => 'SPRING_TENSION',
|
|
'name' => 'Tension Spring',
|
|
'description' => 'Spring for screen tension adjustment',
|
|
'unit' => 'EA',
|
|
'weight' => 0.05,
|
|
'color' => 'SILVER'
|
|
]
|
|
];
|
|
|
|
foreach ($materials as $materialData) {
|
|
Material::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => $materialData['code']
|
|
],
|
|
array_merge($materialData, [
|
|
'category_id' => $category->id,
|
|
'is_active' => true,
|
|
'created_by' => 1
|
|
])
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create design models with parameters, formulas, and rules
|
|
*/
|
|
private function createDesignModels(Tenant $tenant, Category $category): void
|
|
{
|
|
// Create basic screen door model
|
|
$basicModel = DesignModel::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => 'BSD01'
|
|
],
|
|
[
|
|
'name' => 'Basic Screen Door',
|
|
'category_id' => $category->id,
|
|
'lifecycle' => 'ACTIVE',
|
|
'description' => 'Basic parametric screen door model for testing',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
$this->createModelParameters($tenant, $basicModel);
|
|
$this->createModelFormulas($tenant, $basicModel);
|
|
$this->createBomConditionRules($tenant, $basicModel);
|
|
$this->createBomTemplate($tenant, $basicModel);
|
|
|
|
// Create advanced screen door model
|
|
$advancedModel = DesignModel::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'code' => 'ASD01'
|
|
],
|
|
[
|
|
'name' => 'Advanced Screen Door',
|
|
'category_id' => $category->id,
|
|
'lifecycle' => 'ACTIVE',
|
|
'description' => 'Advanced parametric screen door model with more features',
|
|
'is_active' => true
|
|
]
|
|
);
|
|
|
|
$this->createAdvancedModelParameters($tenant, $advancedModel);
|
|
$this->createAdvancedModelFormulas($tenant, $advancedModel);
|
|
$this->createAdvancedBomConditionRules($tenant, $advancedModel);
|
|
}
|
|
|
|
/**
|
|
* Create basic model parameters
|
|
*/
|
|
private function createModelParameters(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$parameters = [
|
|
[
|
|
'parameter_name' => 'width',
|
|
'parameter_type' => 'NUMBER',
|
|
'is_required' => true,
|
|
'default_value' => '1000',
|
|
'min_value' => 500,
|
|
'max_value' => 3000,
|
|
'unit' => 'mm',
|
|
'description' => 'Screen width',
|
|
'sort_order' => 1
|
|
],
|
|
[
|
|
'parameter_name' => 'height',
|
|
'parameter_type' => 'NUMBER',
|
|
'is_required' => true,
|
|
'default_value' => '2000',
|
|
'min_value' => 1000,
|
|
'max_value' => 3000,
|
|
'unit' => 'mm',
|
|
'description' => 'Screen height',
|
|
'sort_order' => 2
|
|
],
|
|
[
|
|
'parameter_name' => 'screen_type',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => true,
|
|
'default_value' => 'FABRIC',
|
|
'options' => ['FABRIC', 'STEEL_FINE', 'STEEL_COARSE'],
|
|
'description' => 'Type of screen material',
|
|
'sort_order' => 3
|
|
],
|
|
[
|
|
'parameter_name' => 'installation_type',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => true,
|
|
'default_value' => 'WALL',
|
|
'options' => ['WALL', 'CEILING', 'RECESSED'],
|
|
'description' => 'Installation method',
|
|
'sort_order' => 4
|
|
],
|
|
[
|
|
'parameter_name' => 'motor_power',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => false,
|
|
'default_value' => 'AUTO',
|
|
'options' => ['AUTO', '12V', '24V'],
|
|
'description' => 'Motor power selection (AUTO = based on size)',
|
|
'sort_order' => 5
|
|
]
|
|
];
|
|
|
|
foreach ($parameters as $paramData) {
|
|
ModelParameter::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'parameter_name' => $paramData['parameter_name']
|
|
],
|
|
$paramData
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create basic model formulas
|
|
*/
|
|
private function createModelFormulas(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$formulas = [
|
|
[
|
|
'formula_name' => 'outer_width',
|
|
'expression' => 'width + 100',
|
|
'description' => 'Outer width including frame',
|
|
'sort_order' => 1
|
|
],
|
|
[
|
|
'formula_name' => 'outer_height',
|
|
'expression' => 'height + 150',
|
|
'description' => 'Outer height including frame',
|
|
'sort_order' => 2
|
|
],
|
|
[
|
|
'formula_name' => 'screen_area',
|
|
'expression' => '(width * height) / 1000000',
|
|
'description' => 'Screen area in square meters',
|
|
'sort_order' => 3
|
|
],
|
|
[
|
|
'formula_name' => 'frame_perimeter',
|
|
'expression' => '(outer_width + outer_height) * 2 / 1000',
|
|
'description' => 'Frame perimeter in meters',
|
|
'sort_order' => 4
|
|
],
|
|
[
|
|
'formula_name' => 'total_weight',
|
|
'expression' => 'screen_area * 0.5 + frame_perimeter * 0.8',
|
|
'description' => 'Estimated total weight in kg',
|
|
'sort_order' => 5
|
|
]
|
|
];
|
|
|
|
foreach ($formulas as $formulaData) {
|
|
ModelFormula::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'formula_name' => $formulaData['formula_name']
|
|
],
|
|
$formulaData
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create BOM condition rules for basic model
|
|
*/
|
|
private function createBomConditionRules(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$rules = [
|
|
// Motor selection based on size
|
|
[
|
|
'rule_name' => 'Large Screen Motor',
|
|
'condition_expression' => 'screen_area > 4.0 OR motor_power == "24V"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'MOTOR_DC_24V')->first()->id,
|
|
'quantity_multiplier' => 1,
|
|
'description' => 'Use 24V motor for large screens',
|
|
'sort_order' => 1
|
|
],
|
|
[
|
|
'rule_name' => 'Standard Screen Motor',
|
|
'condition_expression' => 'screen_area <= 4.0 AND motor_power != "24V"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'MOTOR_DC_12V')->first()->id,
|
|
'quantity_multiplier' => 1,
|
|
'description' => 'Use 12V motor for standard screens',
|
|
'sort_order' => 2
|
|
],
|
|
// 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_SCREEN_STD')->first()->id,
|
|
'quantity_multiplier' => 1.1, // 10% waste
|
|
'description' => 'Standard fabric screen material',
|
|
'sort_order' => 3
|
|
],
|
|
[
|
|
'rule_name' => 'Fine Steel Screen Material',
|
|
'condition_expression' => 'screen_type == "STEEL_FINE"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'MATERIAL',
|
|
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'STEEL_MESH_FINE')->first()->id,
|
|
'quantity_multiplier' => 1.05, // 5% waste
|
|
'description' => 'Fine steel mesh material',
|
|
'sort_order' => 4
|
|
],
|
|
// Bracket selection based on installation
|
|
[
|
|
'rule_name' => 'Wall Brackets',
|
|
'condition_expression' => 'installation_type == "WALL"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BRACKET_WALL_STD')->first()->id,
|
|
'quantity_multiplier' => 2, // Always 2 brackets
|
|
'description' => 'Wall mounting brackets',
|
|
'sort_order' => 5
|
|
],
|
|
[
|
|
'rule_name' => 'Ceiling Brackets',
|
|
'condition_expression' => 'installation_type == "CEILING"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BRACKET_CEILING_STD')->first()->id,
|
|
'quantity_multiplier' => 2,
|
|
'description' => 'Ceiling mounting brackets',
|
|
'sort_order' => 6
|
|
],
|
|
// Extra brackets for wide screens
|
|
[
|
|
'rule_name' => 'Extra Brackets for Wide Screens',
|
|
'condition_expression' => 'width > 2000',
|
|
'action_type' => 'MODIFY_QUANTITY',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'BRACKET_WALL_STD')->first()->id,
|
|
'quantity_multiplier' => 1.5, // Add 50% more brackets
|
|
'description' => 'Additional brackets for wide screens',
|
|
'sort_order' => 7
|
|
]
|
|
];
|
|
|
|
foreach ($rules as $ruleData) {
|
|
BomConditionRule::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'rule_name' => $ruleData['rule_name']
|
|
],
|
|
$ruleData
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create BOM template for basic model
|
|
*/
|
|
private function createBomTemplate(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
// Create model version first
|
|
$modelVersion = ModelVersion::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'version_no' => '1.0'
|
|
],
|
|
[
|
|
'status' => 'RELEASED',
|
|
'description' => 'Initial release version',
|
|
'created_by' => 1
|
|
]
|
|
);
|
|
|
|
// Create BOM template
|
|
$bomTemplate = BomTemplate::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_version_id' => $modelVersion->id,
|
|
'name' => 'Basic Screen Door BOM'
|
|
],
|
|
[
|
|
'description' => 'Base BOM template for basic screen door',
|
|
'is_active' => true,
|
|
'created_by' => 1
|
|
]
|
|
);
|
|
|
|
// Create BOM template items (base components always included)
|
|
$baseItems = [
|
|
[
|
|
'ref_type' => 'MATERIAL',
|
|
'ref_id' => Material::where('tenant_id', $tenant->id)->where('code', 'RAIL_GUIDE_ALU')->first()->id,
|
|
'quantity' => 1, // Will be calculated by formula
|
|
'waste_rate' => 5,
|
|
'order' => 1
|
|
],
|
|
[
|
|
'ref_type' => 'MATERIAL',
|
|
'ref_id' => Material::where('tenant_id', $tenant->id)->where('code', 'CABLE_STEEL')->first()->id,
|
|
'quantity' => 2, // Height * 2
|
|
'waste_rate' => 10,
|
|
'order' => 2
|
|
],
|
|
[
|
|
'ref_type' => 'MATERIAL',
|
|
'ref_id' => Material::where('tenant_id', $tenant->id)->where('code', 'SPRING_TENSION')->first()->id,
|
|
'quantity' => 2,
|
|
'waste_rate' => 0,
|
|
'order' => 3
|
|
],
|
|
[
|
|
'ref_type' => 'PRODUCT',
|
|
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CONTROLLER_BASIC')->first()->id,
|
|
'quantity' => 1,
|
|
'waste_rate' => 0,
|
|
'order' => 4
|
|
],
|
|
[
|
|
'ref_type' => 'PRODUCT',
|
|
'ref_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CASE_ALUMINUM')->first()->id,
|
|
'quantity' => 1,
|
|
'waste_rate' => 0,
|
|
'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
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create advanced model parameters
|
|
*/
|
|
private function createAdvancedModelParameters(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$parameters = [
|
|
[
|
|
'parameter_name' => 'width',
|
|
'parameter_type' => 'NUMBER',
|
|
'is_required' => true,
|
|
'default_value' => '1200',
|
|
'min_value' => 600,
|
|
'max_value' => 4000,
|
|
'unit' => 'mm',
|
|
'description' => 'Screen width',
|
|
'sort_order' => 1
|
|
],
|
|
[
|
|
'parameter_name' => 'height',
|
|
'parameter_type' => 'NUMBER',
|
|
'is_required' => true,
|
|
'default_value' => '2200',
|
|
'min_value' => 1200,
|
|
'max_value' => 3500,
|
|
'unit' => 'mm',
|
|
'description' => 'Screen height',
|
|
'sort_order' => 2
|
|
],
|
|
[
|
|
'parameter_name' => 'screen_type',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => true,
|
|
'default_value' => 'FABRIC_PREMIUM',
|
|
'options' => ['FABRIC_STD', 'FABRIC_PREMIUM', 'STEEL_FINE', 'STEEL_COARSE'],
|
|
'description' => 'Type of screen material',
|
|
'sort_order' => 3
|
|
],
|
|
[
|
|
'parameter_name' => 'controller_type',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => true,
|
|
'default_value' => 'SMART',
|
|
'options' => ['BASIC', 'SMART'],
|
|
'description' => 'Controller type',
|
|
'sort_order' => 4
|
|
],
|
|
[
|
|
'parameter_name' => 'case_material',
|
|
'parameter_type' => 'SELECT',
|
|
'is_required' => true,
|
|
'default_value' => 'ALUMINUM',
|
|
'options' => ['ALUMINUM', 'PLASTIC'],
|
|
'description' => 'Case material',
|
|
'sort_order' => 5
|
|
],
|
|
[
|
|
'parameter_name' => 'wind_resistance',
|
|
'parameter_type' => 'NUMBER',
|
|
'is_required' => false,
|
|
'default_value' => '80',
|
|
'min_value' => 40,
|
|
'max_value' => 120,
|
|
'unit' => 'km/h',
|
|
'description' => 'Required wind resistance',
|
|
'sort_order' => 6
|
|
]
|
|
];
|
|
|
|
foreach ($parameters as $paramData) {
|
|
ModelParameter::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'parameter_name' => $paramData['parameter_name']
|
|
],
|
|
$paramData
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create advanced model formulas
|
|
*/
|
|
private function createAdvancedModelFormulas(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$formulas = [
|
|
[
|
|
'formula_name' => 'outer_width',
|
|
'expression' => 'width + 120',
|
|
'description' => 'Outer width including reinforced frame',
|
|
'sort_order' => 1
|
|
],
|
|
[
|
|
'formula_name' => 'outer_height',
|
|
'expression' => 'height + 180',
|
|
'description' => 'Outer height including reinforced frame',
|
|
'sort_order' => 2
|
|
],
|
|
[
|
|
'formula_name' => 'screen_area',
|
|
'expression' => '(width * height) / 1000000',
|
|
'description' => 'Screen area in square meters',
|
|
'sort_order' => 3
|
|
],
|
|
[
|
|
'formula_name' => 'wind_load',
|
|
'expression' => 'screen_area * wind_resistance * 0.6',
|
|
'description' => 'Wind load calculation in Newtons',
|
|
'sort_order' => 4
|
|
],
|
|
[
|
|
'formula_name' => 'required_motor_torque',
|
|
'expression' => 'wind_load * 0.1 + screen_area * 5',
|
|
'description' => 'Required motor torque in Nm',
|
|
'sort_order' => 5
|
|
],
|
|
[
|
|
'formula_name' => 'frame_sections_count',
|
|
'expression' => 'ceiling(width / 600) + ceiling(height / 800)',
|
|
'description' => 'Number of frame sections needed',
|
|
'sort_order' => 6
|
|
]
|
|
];
|
|
|
|
foreach ($formulas as $formulaData) {
|
|
ModelFormula::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'formula_name' => $formulaData['formula_name']
|
|
],
|
|
$formulaData
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create advanced BOM condition rules
|
|
*/
|
|
private function createAdvancedBomConditionRules(Tenant $tenant, DesignModel $model): void
|
|
{
|
|
$rules = [
|
|
// Motor selection based on calculated torque
|
|
[
|
|
'rule_name' => 'High Torque Motor Required',
|
|
'condition_expression' => 'required_motor_torque > 15 OR wind_resistance > 100',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'MOTOR_DC_24V')->first()->id,
|
|
'quantity_multiplier' => 1,
|
|
'description' => 'Use high-power motor for demanding conditions',
|
|
'sort_order' => 1
|
|
],
|
|
// Screen material selection
|
|
[
|
|
'rule_name' => 'Premium Fabric Material',
|
|
'condition_expression' => 'screen_type == "FABRIC_PREMIUM"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'MATERIAL',
|
|
'target_id' => Material::where('tenant_id', $tenant->id)->where('code', 'FABRIC_SCREEN_PREMIUM')->first()->id,
|
|
'quantity_multiplier' => 1.05,
|
|
'description' => 'Premium fabric screen material',
|
|
'sort_order' => 2
|
|
],
|
|
// Controller selection
|
|
[
|
|
'rule_name' => 'Smart Controller',
|
|
'condition_expression' => 'controller_type == "SMART"',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CONTROLLER_SMART')->first()->id,
|
|
'quantity_multiplier' => 1,
|
|
'description' => 'Smart controller with app connectivity',
|
|
'sort_order' => 3
|
|
],
|
|
// Case material selection
|
|
[
|
|
'rule_name' => 'Plastic Case for Light Duty',
|
|
'condition_expression' => 'case_material == "PLASTIC" AND wind_resistance <= 60',
|
|
'action_type' => 'INCLUDE',
|
|
'target_type' => 'PRODUCT',
|
|
'target_id' => Product::where('tenant_id', $tenant->id)->where('code', 'CASE_PLASTIC')->first()->id,
|
|
'quantity_multiplier' => 1,
|
|
'description' => 'Plastic case for light-duty applications',
|
|
'sort_order' => 4
|
|
]
|
|
];
|
|
|
|
foreach ($rules as $ruleData) {
|
|
BomConditionRule::firstOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'model_id' => $model->id,
|
|
'rule_name' => $ruleData['rule_name']
|
|
],
|
|
$ruleData
|
|
);
|
|
}
|
|
}
|
|
}
|