option('plan')); if (! in_array($plan, ['free', 'pro', 'enterprise'], true)) { $this->error('Invalid --plan. Use free, pro, or enterprise.'); return self::FAILURE; } $user = $this->resolveUser((string) $this->argument('identity')); if (! $user) { $this->error('User not found for identity: '.$this->argument('identity')); return self::FAILURE; } if ($this->option('reset')) { $this->resetTenant($user); $this->info('Reset demo data for '.$user->email); } $this->assignPlan($subscriptions, $user, $plan); $existing = WooStore::query() ->where('user_id', $user->id) ->where('metadata->demo', true) ->count(); if ($existing > 0 && ! $this->option('reset')) { $this->info('Demo stores already present; plan ensured (idempotent).'); $this->line(sprintf('user=%s plan=%s stores=%d', $user->email, $plan, $existing)); return self::SUCCESS; } $storeSpecs = $this->storeSpecs($plan); foreach ($storeSpecs as $spec) { $this->seedStore($user, $spec); } $this->info(sprintf( 'Seeded %d demo store(s) for %s (%s).', count($storeSpecs), $user->email, $plan, )); return self::SUCCESS; } private function resolveUser(string $identity): ?User { return User::query() ->where(function ($query) use ($identity) { $query->where('email', $identity)->orWhere('public_id', $identity); }) ->first(); } private function assignPlan(SubscriptionService $subscriptions, User $user, string $plan): void { if ($plan === 'free') { ProSubscription::query()->where('user_id', $user->id)->delete(); return; } $subscriptions->activatePrepaid( $user, $plan === 'enterprise' ? ProSubscription::PLAN_ENTERPRISE : ProSubscription::PLAN_PRO, 12, ); } private function resetTenant(User $user): void { DB::transaction(function () use ($user) { WooStore::query()->where('user_id', $user->id)->each(function (WooStore $store) { $store->delete(); }); ProSubscription::query()->where('user_id', $user->id)->delete(); }); } /** * @return list}> */ private function storeSpecs(string $plan): array { $baseCategories = ['Apparel', 'Accessories', 'Home']; $businessName = DemoWorld::business($plan)['name']; return match ($plan) { 'enterprise' => [ [ 'site_name' => $businessName.' Shop', 'site_url' => 'https://demo-accra.example.com', 'products' => 30, 'orders' => 12, 'categories' => $baseCategories, ], [ 'site_name' => $businessName.' — Kumasi Branch Shop', 'site_url' => 'https://demo-kumasi.example.com', 'products' => 24, 'orders' => 8, 'categories' => ['Electronics', 'Gadgets'], ], [ 'site_name' => $businessName.' Wholesale', 'site_url' => 'https://demo-wholesale.example.com', 'products' => 20, 'orders' => 6, 'categories' => ['Bulk', 'Packaging'], ], ], 'pro' => [ [ 'site_name' => $businessName.' Shop', 'site_url' => 'https://demo-pro-shop.example.com', 'products' => 35, 'orders' => 10, 'categories' => $baseCategories, ], [ 'site_name' => $businessName.' Outlet', 'site_url' => 'https://demo-outlet.example.com', 'products' => 15, 'orders' => 5, 'categories' => ['Clearance', 'Seasonal'], ], ], default => [ [ 'site_name' => $businessName.' Shop', 'site_url' => 'https://demo-free-shop.example.com', 'products' => 15, 'orders' => 4, 'categories' => $baseCategories, ], ], }; } /** * @param array{site_name: string, site_url: string, products: int, orders: int, categories: list} $spec */ private function seedStore(User $user, array $spec): void { $store = WooStore::query()->create([ 'user_id' => $user->id, 'site_url' => $spec['site_url'], 'site_name' => $spec['site_name'], 'status' => WooStore::STATUS_ACTIVE, 'connected_at' => now(), 'metadata' => [ 'demo' => true, 'currency' => 'GHS', ], ]); $categoryIds = []; foreach ($spec['categories'] as $i => $name) { $externalId = $i + 1; WooCategory::query()->create([ 'woo_store_id' => $store->id, 'external_id' => $externalId, 'name' => $name, 'slug' => Str::slug($name), 'product_count' => 0, ]); $categoryIds[] = $externalId; } $products = []; for ($i = 1; $i <= $spec['products']; $i++) { $cat = $categoryIds[($i - 1) % max(count($categoryIds), 1)] ?? null; $product = WooProduct::query()->create([ 'woo_store_id' => $store->id, 'external_id' => $i, 'name' => sprintf('%s Product %02d', $spec['site_name'], $i), 'slug' => 'demo-product-'.$store->id.'-'.$i, 'sku' => 'DEMO-'.$store->id.'-'.$i, 'status' => WooProduct::STATUS_PUBLISH, 'type' => 'simple', 'regular_price_minor' => 2_500 + ($i * 100), 'stock_quantity' => 10 + $i, 'manage_stock' => true, 'category_external_ids' => $cat ? [$cat] : [], 'short_description' => 'Local demo product (no live WordPress).', ]); $products[] = $product; if ($cat) { WooCategory::query() ->where('woo_store_id', $store->id) ->where('external_id', $cat) ->increment('product_count'); } } $people = DemoWorld::people(); for ($i = 1; $i <= $spec['orders']; $i++) { $product = $products[($i - 1) % count($products)]; $qty = 1 + ($i % 3); $lineTotal = (int) $product->regular_price_minor * $qty; $customer = $people[($i - 1) % count($people)]; WooOrder::query()->create([ 'woo_store_id' => $store->id, 'external_order_id' => 1000 + $i, 'order_number' => (string) (1000 + $i), 'wc_status' => $i % 4 === 0 ? 'completed' : 'processing', 'payment_status' => 'paid', 'customer_name' => DemoWorld::fullName($customer), 'customer_email' => $customer['email'], 'customer_phone' => $customer['phone'], 'line_items' => [[ 'id' => $product->external_id, 'name' => $product->name, 'quantity' => $qty, 'total' => number_format($lineTotal / 100, 2, '.', ''), 'sku' => $product->sku, ]], 'currency' => 'GHS', 'total_minor' => $lineTotal, 'fulfillment_status' => $i % 3 === 0 ? WooOrder::FULFILLMENT_DELIVERED : WooOrder::FULFILLMENT_NEW, 'wc_updated_at' => now()->subDays($spec['orders'] - $i), 'metadata' => ['demo' => true], ]); } } }