option('recreate')) { if (! $this->confirm('Are you sure you want to DELETE ALL EXISTING PERFUMES and recreate them? This action cannot be undone.')) { $this->info('Migration cancelled.'); return; } $this->warn('Deleting all existing perfumes...'); Perfume::query()->delete(); // This will cascade delete outlet relations $this->info('All perfumes deleted.'); } elseif (! $this->option('force') && ! $this->confirm('Are you sure you want to migrate perfumes data? This will add new perfumes to your database.')) { $this->info('Migration cancelled.'); return; } $this->info('Starting perfumes migration...'); try { $oldFragrances = DB::connection('old_database')->table('fragrances')->whereNull('deleted_at')->get(); $this->info("Found {$oldFragrances->count()} perfumes to migrate."); $bar = $this->output->createProgressBar($oldFragrances->count()); $migrated = 0; $skipped = 0; foreach ($oldFragrances as $oldFragrance) { $existingPerfume = Perfume::where('name', $oldFragrance->name)->first(); if (! $this->option('recreate') && $existingPerfume) { $this->warn("Perfume '{$oldFragrance->name}' already exists, skipping..."); $skipped++; $bar->advance(); continue; } $perfume = Perfume::create([ 'brand_id' => $oldFragrance->brand_id, 'name' => $oldFragrance->name, 'slug' => Str::slug($oldFragrance->name), 'concentration' => Concentration::EXTRAIT_DE_PERFUME, // Default concentration 'cost_price' => $oldFragrance->buying_price, 'sale_price' => $oldFragrance->selling_price, 'base_notes' => null, 'middle_notes' => null, 'top_notes' => null, 'description' => null, 'views' => 0, 'created_at' => $oldFragrance->created_at, 'updated_at' => $oldFragrance->updated_at, ]); // Attach category if exists if (isset($oldFragrance->categories_id) && $oldFragrance->categories_id) { $perfume->categories()->attach($oldFragrance->categories_id); } // Create outlet relations from fragrance_stocks $this->createPerfumeOutletRelations($perfume->id, $oldFragrance->id); $migrated++; $bar->advance(); } $bar->finish(); $this->newLine(2); $this->info('✅ Perfumes migration completed!'); $this->info("📊 Migrated: {$migrated} perfumes"); $this->info("⏭️ Skipped: {$skipped} perfumes (already exist)"); } catch (\Exception $e) { $this->error("❌ Migration failed: {$e->getMessage()}"); return 1; } return 0; } private function createPerfumeOutletRelations(int $newPerfumeId, int $oldFragranceId): void { try { // Get fragrance stocks from old database $fragranceStocks = DB::connection('old_database') ->table('fragrance_stocks') ->where('fragrance_id', $oldFragranceId) ->get(); foreach ($fragranceStocks as $stock) { // Map old store_id to new outlet_id $outletMapping = $this->getOutletMapping(); $outletId = $outletMapping[$stock->store_id] ?? null; if ($outletId) { // Create many-to-many relation with stock amount DB::table('outlet_perfume')->insert([ 'outlet_id' => $outletId, 'perfume_id' => $newPerfumeId, 'stock' => $stock->amount, 'created_at' => now(), 'updated_at' => now(), ]); } } } catch (\Exception $e) { $this->warn("Could not create outlet relations for perfume ID {$newPerfumeId}: {$e->getMessage()}"); } } private function getOutletMapping(): array { // Map old store_id to new outlet_id // This assumes outlets have been migrated first $outlets = Outlet::select('id')->orderBy('id')->get(); $mapping = []; foreach ($outlets as $index => $outlet) { $mapping[$index + 1] = $outlet->id; // Old store_id starts from 1 } return $mapping; } }