'personal', 'name' => 'Personal'], [ 'price_aud' => 10.00, 'billing_interval' => 'year', 'sms_included' => 50, 'max_tags' => 25, 'alerts_per_day' => 5, 'alerts_per_hour' => 10, ] ); // 2. Tag + credit SKUs (idempotent by sku). $skus = [ ['sku' => 'TAG-SINGLE', 'name' => 'Where Woof Tag (single)', 'item_type' => 'other', 'price_aud' => 5.00], ['sku' => 'TAG-10PACK', 'name' => 'Where Woof Tags (10-pack)', 'item_type' => 'other', 'price_aud' => 20.00], ['sku' => 'SMS-CREDITS-100', 'name' => '100 SMS Credits', 'item_type' => 'other', 'price_aud' => 10.00], ]; foreach ($skus as $s) { Product::firstOrCreate(['sku' => $s['sku']], $s); } // 3. Paid order for any account that owns tags (dev regression safety), // plus the known dev accounts (admin + owner) so verify suites that // bind tags after a DB reset still alert under account-level gating. $tagOwners = DB::table('tags') ->whereNotNull('owner_id') ->distinct() ->pluck('owner_id'); $devEmails = ['admin@where-woof.com', 'owner@where-woof.com']; foreach (User::whereIn('email', $devEmails)->get() as $dev) { $tagOwners->push($dev->id); } $tagOwners = $tagOwners->unique(); foreach ($tagOwners as $ownerId) { $existing = Order::where('account_id', $ownerId)->where('status', 'paid')->first(); if ($existing) { continue; } Order::create([ 'account_id' => $ownerId, 'status' => 'paid', 'plan_id' => $plan->id, 'period_started_at' => now(), 'renews_at' => now()->addYear(), 'amount' => 10.00, ]); } $this->command?->info('BillingSeeder: plan + '.count($skus).' SKUs seeded; '.$tagOwners->count().' dev accounts given paid orders.'); } }