value('id'); if (! $businessId) { $this->command?->warn('No business found — skipping enterprise sample seed.'); return; } $userId = (int) DB::table('users')->where('business_id', $businessId)->value('id'); $this->seedQms($businessId, $userId); $this->seedShopFloor($businessId, $userId); $this->seedSupplyChain($businessId); $this->seedAdvancedPlanning($businessId); $this->seedIntegrationHub($businessId); $this->seedCpq($businessId, $userId); $this->seedWms($businessId); $this->seedIot($businessId); $this->registerModuleVersions(); $this->grantEnterprisePermissions($businessId); $this->command?->info("Enterprise sample data seeded for business #{$businessId}."); } protected function seedQms(int $businessId, int $userId): void { if (! Schema::hasTable('qms_ncr_reports')) { return; } if (DB::table('qms_ncr_reports')->where('business_id', $businessId)->exists()) { return; } $ncrId = DB::table('qms_ncr_reports')->insertGetId([ 'business_id' => $businessId, 'ref_no' => 'NCR-00001', 'title' => 'Dimensional deviation on machined shaft', 'description' => 'Sample NCR for executive cockpit demo.', 'severity' => 'major', 'source' => 'production', 'status' => 'investigating', 'reported_by' => $userId ?: null, 'detected_at' => Carbon::today()->subDays(3)->toDateString(), 'created_at' => now(), 'updated_at' => now(), ]); DB::table('qms_capa_actions')->insert([ 'business_id' => $businessId, 'ncr_id' => $ncrId, 'ref_no' => 'CAPA-00001', 'type' => 'corrective', 'title' => 'Recalibrate CNC offset and retrain operator', 'status' => 'in_progress', 'owner_id' => $userId ?: null, 'due_date' => Carbon::today()->addDays(14)->toDateString(), 'created_at' => now(), 'updated_at' => now(), ]); DB::table('qms_fmea_records')->insert([ 'business_id' => $businessId, 'ref_no' => 'FMEA-00001', 'process_step' => 'Final assembly torque', 'failure_mode' => 'Under-torque', 'severity' => 8, 'occurrence' => 4, 'detection' => 3, 'rpn' => 96, 'status' => 'active', 'created_at' => now(), 'updated_at' => now(), ]); for ($i = 0; $i < 5; $i++) { DB::table('qms_spc_measurements')->insert([ 'business_id' => $businessId, 'characteristic_name' => 'shaft_diameter_mm', 'measured_value' => 49.98 + ($i * 0.01), 'usl' => 50.05, 'lsl' => 49.95, 'target' => 50.00, 'measured_at' => now()->subDays($i), 'in_control' => true, 'recorded_by' => $userId ?: null, 'created_at' => now(), 'updated_at' => now(), ]); } DB::table('qms_calibration_assets')->insert([ 'business_id' => $businessId, 'asset_tag' => 'CAL-001', 'name' => 'Digital micrometer 0-150mm', 'status' => 'active', 'calibration_interval_days' => 180, 'next_due_at' => Carbon::today()->addMonths(3)->toDateString(), 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedShopFloor(int $businessId, int $userId): void { if (! Schema::hasTable('sf_work_centers') || DB::table('sf_work_centers')->where('business_id', $businessId)->exists()) { return; } $wcId = DB::table('sf_work_centers')->insertGetId([ 'business_id' => $businessId, 'name' => 'Assembly Line A', 'code' => 'WC-A01', 'capacity_per_hour' => 12, 'status' => 'active', 'created_at' => now(), 'updated_at' => now(), ]); DB::table('sf_production_events')->insert([ 'business_id' => $businessId, 'work_center_id' => $wcId, 'event_type' => 'complete', 'quantity' => 48, 'good_quantity' => 46, 'scrap_quantity' => 2, 'recorded_at' => now()->subHours(2), 'recorded_by' => $userId ?: null, 'created_at' => now(), 'updated_at' => now(), ]); DB::table('sf_oee_snapshots')->insert([ 'business_id' => $businessId, 'work_center_id' => $wcId, 'snapshot_date' => Carbon::today()->toDateString(), 'availability_pct' => 92.5, 'performance_pct' => 88.0, 'quality_pct' => 95.8, 'oee_pct' => 78.1, 'planned_minutes' => 480, 'run_minutes' => 444, 'downtime_minutes' => 36, 'ideal_output' => 96, 'actual_output' => 48, 'good_output' => 46, 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedSupplyChain(int $businessId): void { if (! Schema::hasTable('sc_supplier_scorecards')) { return; } if (DB::table('sc_supplier_scorecards')->where('business_id', $businessId)->exists()) { return; } $supplierId = DB::table('contacts') ->where('business_id', $businessId) ->whereIn('type', ['supplier', 'both']) ->value('id'); DB::table('sc_supplier_scorecards')->insert([ 'business_id' => $businessId, 'contact_id' => $supplierId, 'period_start' => Carbon::today()->startOfMonth()->toDateString(), 'period_end' => Carbon::today()->endOfMonth()->toDateString(), 'otif_score' => 87.5, 'quality_score' => 92.0, 'price_score' => 78.0, 'responsiveness_score' => 85.0, 'overall_score' => 85.6, 'risk_level' => 'low', 'created_at' => now(), 'updated_at' => now(), ]); DB::table('sc_demand_forecasts')->insert([ 'business_id' => $businessId, 'forecast_month' => Carbon::today()->addMonth()->format('Y-m-01'), 'forecast_qty' => 120, 'method' => 'moving_average', 'confidence' => 0.82, 'source' => 'sales_history', 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedAdvancedPlanning(int $businessId): void { if (! Schema::hasTable('ap_capacity_resources') || DB::table('ap_capacity_resources')->where('business_id', $businessId)->exists()) { return; } DB::table('ap_capacity_resources')->insert([ 'business_id' => $businessId, 'name' => 'Main Assembly Line', 'resource_type' => 'line', 'daily_capacity_hours' => 16, 'efficiency_pct' => 85, 'created_at' => now(), 'updated_at' => now(), ]); DB::table('ap_sop_cycles')->insert([ 'business_id' => $businessId, 'cycle_month' => Carbon::today()->format('Y-m-01'), 'status' => 'draft', 'demand_plan' => json_encode(['units' => 500, 'revenue' => 2500000]), 'supply_plan' => json_encode(['capacity_hours' => 320, 'open_wo' => 12]), 'financial_plan' => json_encode(['cogs' => 1800000, 'margin_pct' => 28]), 'gaps' => json_encode(['capacity_gap_hours' => 24]), 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedIntegrationHub(int $businessId): void { if (! Schema::hasTable('ih_webhook_endpoints') || DB::table('ih_webhook_endpoints')->where('business_id', $businessId)->exists()) { return; } DB::table('ih_webhook_endpoints')->insert([ 'business_id' => $businessId, 'name' => 'Power BI / External BI', 'url' => 'https://example.com/webhooks/executive-cockpit', 'secret' => bin2hex(random_bytes(16)), 'events' => json_encode(['executive_cockpit.exported', 'export.completed']), 'is_active' => false, 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedCpq(int $businessId, int $userId): void { if (! Schema::hasTable('ie_cpq_configurations') || DB::table('ie_cpq_configurations')->where('business_id', $businessId)->exists()) { return; } DB::table('ie_cpq_configurations')->insert([ 'business_id' => $businessId, 'name' => 'Custom press line configuration', 'ref_no' => 'CPQ-00001', 'status' => 'quoted', 'selected_options' => json_encode([]), 'bom_snapshot' => json_encode(['lines' => []]), 'quoted_price' => 1250000, 'created_by' => $userId ?: null, 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedWms(int $businessId): void { if (! Schema::hasTable('im_wms_waves') || DB::table('im_wms_waves')->where('business_id', $businessId)->exists()) { return; } $locationId = DB::table('business_locations')->where('business_id', $businessId)->value('id') ?? 1; DB::table('im_wms_waves')->insert([ 'business_id' => $businessId, 'location_id' => $locationId, 'wave_no' => 'WAVE-00001', 'status' => 'planned', 'pick_strategy' => 'wave', 'priority' => 100, 'created_at' => now(), 'updated_at' => now(), ]); } protected function seedIot(int $businessId): void { if (! Schema::hasTable('mt_iot_devices') || DB::table('mt_iot_devices')->where('business_id', $businessId)->exists()) { return; } DB::table('mt_iot_devices')->insert([ 'business_id' => $businessId, 'device_uid' => 'DEMO-VIB-001', 'name' => 'Vibration sensor — Press #1', 'protocol' => 'mqtt', 'topic' => 'plant/press1/vibration', 'status' => 'active', 'last_seen_at' => now()->subMinutes(5), 'created_at' => now(), 'updated_at' => now(), ]); } protected function registerModuleVersions(): void { $modules = [ 'qualitymanagement' => '1.0.0', 'shopfloor' => '1.0.0', 'integrationhub' => '1.0.0', 'supplychain' => '1.0.0', 'advancedplanning' => '1.0.0', ]; foreach ($modules as $key => $version) { if (empty(System::getProperty($key.'_version'))) { System::addProperty($key.'_version', $version); } } } protected function grantEnterprisePermissions(int $businessId): void { $permissions = [ 'qms.access', 'qms.ncr.view', 'qms.ncr.create', 'qms.ncr.update', 'qms.capa.view', 'qms.capa.create', 'qms.capa.update', 'qms.fmea.view', 'qms.fmea.create', 'qms.spc.view', 'qms.spc.create', 'qms.calibration.view', 'qms.calibration.create', 'qms.calibration.update', 'qms.audit.view', 'qms.audit.create', 'qms.document.view', 'qms.document.create', 'shopfloor.access', 'shopfloor.view', 'shopfloor.production.create', 'shopfloor.downtime.create', 'shopfloor.oee.view', 'shopfloor.instructions.view', 'integrationhub.access', 'integrationhub.manage_webhooks', 'integrationhub.manage_tokens', 'integrationhub.export', 'supplychain.access', 'supplychain.view', 'supplychain.scorecard.view', 'supplychain.scorecard.create', 'supplychain.forecast.view', 'supplychain.forecast.create', 'supplychain.rfq.view', 'supplychain.rfq.create', 'supplychain.rfq.update', 'ap.access', 'ap.view', 'ap.resources.view', 'ap.resources.manage', 'ap.schedule.view', 'ap.schedule.run', 'ap.sop.view', 'ap.sop.manage', 'ie.cpq.view', 'ie.cpq.create', ]; foreach ($permissions as $name) { Permission::firstOrCreate(['name' => $name, 'guard_name' => 'web']); } $role = Role::where('name', 'Admin#'.$businessId)->first(); if ($role) { $role->givePermissionTo($permissions); } } }