option('recreate')) { if (! $this->confirm('Are you sure you want to DELETE ALL EXISTING PRODUCTS and recreate them? This action cannot be undone.')) { $this->info('Migration cancelled.'); return; } $this->warn('Deleting all existing products...'); Product::query()->delete(); // This will cascade delete outlet relations $this->info('All products deleted.'); } elseif (! $this->option('force') && ! $this->confirm('Are you sure you want to migrate products data? This will add new products to your database.')) { $this->info('Migration cancelled.'); return; } $this->info('Starting products migration...'); try { $oldProducts = DB::connection('old_database')->table('products')->whereNull('deleted_at')->get(); $this->info("Found {$oldProducts->count()} products to migrate."); $bar = $this->output->createProgressBar($oldProducts->count()); $migrated = 0; $skipped = 0; foreach ($oldProducts as $oldProduct) { $existingProduct = Product::where('name', $oldProduct->name)->first(); if (! $this->option('recreate') && $existingProduct) { $this->warn("Product '{$oldProduct->name}' already exists, skipping..."); $skipped++; $bar->advance(); continue; } $product = Product::create([ 'name' => $oldProduct->name, 'slug' => Str::slug($oldProduct->name), 'sku' => $this->generateSKU('PROD', $oldProduct->id), 'cost_price' => $oldProduct->buying_price, 'sale_price' => $oldProduct->selling_price, 'description' => null, 'views' => 0, 'created_at' => $oldProduct->created_at, 'updated_at' => $oldProduct->updated_at, ]); // Create outlet relations from product_stocks $this->createProductOutletRelations($product->id, $oldProduct->id); $migrated++; $bar->advance(); } $bar->finish(); $this->newLine(2); $this->info('✅ Products migration completed!'); $this->info("📊 Migrated: {$migrated} products"); $this->info("⏭️ Skipped: {$skipped} products (already exist)"); } catch (\Exception $e) { $this->error("❌ Migration failed: {$e->getMessage()}"); return 1; } return 0; } private function createProductOutletRelations(int $newProductId, int $oldProductId): void { try { // Get product stocks from old database $productStocks = DB::connection('old_database') ->table('product_stocks') ->where('product_id', $oldProductId) ->get(); foreach ($productStocks 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_product')->insert([ 'outlet_id' => $outletId, 'product_id' => $newProductId, 'stock' => $stock->amount, 'created_at' => now(), 'updated_at' => now(), ]); } } } catch (\Exception $e) { $this->warn("Could not create outlet relations for product ID {$newProductId}: {$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; } private function generateSKU(string $prefix, int $id): string { // Use timestamp to ensure uniqueness when recreating $timestamp = now()->format('His'); return $prefix.str_pad($id, 3, '0', STR_PAD_LEFT).$timestamp; } }