diff --git a/app/Http/Controllers/Api/IntegrationController.php b/app/Http/Controllers/Api/IntegrationController.php index d012c4e..013f991 100644 --- a/app/Http/Controllers/Api/IntegrationController.php +++ b/app/Http/Controllers/Api/IntegrationController.php @@ -100,6 +100,17 @@ class IntegrationController extends Controller AuditLogger::record($owner, 'organization.created', $organization->id, $owner, Organization::class, $organization->id); } else { + $settings = $organization->settings ?? []; + $settings['onboarded'] = true; + if (! empty($validated['organization_name'])) { + $organization->name = $validated['organization_name']; + } + if (! empty($validated['timezone'])) { + $organization->timezone = $validated['timezone']; + } + $settings['industry'] = $industry; + $organization->forceFill(['settings' => $settings])->save(); + $branch = Branch::query() ->where('organization_id', $organization->id) ->where('is_active', true) diff --git a/app/Services/Qms/DemoSeeder.php b/app/Services/Qms/DemoSeeder.php index a11578c..4496e6f 100644 --- a/app/Services/Qms/DemoSeeder.php +++ b/app/Services/Qms/DemoSeeder.php @@ -248,10 +248,27 @@ class DemoSeeder } Department::withTrashed()->where('owner_ref', $ownerRef)->forceDelete(); - Member::query()->where('owner_ref', $ownerRef)->delete(); + // Keep the owner member + organization so SSO redirects never see + // "not onboarded" while afterResponse() reseeding is still running. + Member::query() + ->where('owner_ref', $ownerRef) + ->where('user_ref', '!=', $ownerRef) + ->delete(); AuditLog::query()->where('owner_ref', $ownerRef)->delete(); Branch::withTrashed()->where('owner_ref', $ownerRef)->forceDelete(); - Organization::withTrashed()->where('owner_ref', $ownerRef)->forceDelete(); + + foreach ($orgIds as $orgId) { + $organization = Organization::withTrashed()->find($orgId); + if (! $organization) { + continue; + } + if ($organization->trashed()) { + $organization->restore(); + } + $settings = $organization->settings ?? []; + $settings['onboarded'] = true; + $organization->forceFill(['settings' => $settings])->save(); + } }); } diff --git a/tests/Feature/DemoSeedCommandTest.php b/tests/Feature/DemoSeedCommandTest.php index ed620b5..b3128ba 100644 --- a/tests/Feature/DemoSeedCommandTest.php +++ b/tests/Feature/DemoSeedCommandTest.php @@ -71,6 +71,34 @@ class DemoSeedCommandTest extends TestCase $this->assertDatabaseHas('queue_organizations', ['id' => $otherOrgId, 'owner_ref' => $other->public_id]); $this->assertSame('pro', app(PlanService::class)->planKey(Organization::owned($target->public_id)->first())); + $this->assertTrue((bool) data_get(Organization::owned($target->public_id)->first()?->settings, 'onboarded')); + $this->assertSame( + $org->id, + Organization::owned($target->public_id)->value('id'), + 'Reset must keep the organization row so login never flashes onboarding', + ); + } + + public function test_reset_keeps_organization_onboarded_mid_wipe(): void + { + $user = User::create([ + 'public_id' => 'demo-queue-mid-reset', + 'name' => 'Demo Mid', + 'email' => 'demo-mid@ladill.com', + 'password' => bcrypt('password'), + ]); + + Artisan::call('demo:seed', ['identity' => $user->email, '--plan' => 'free']); + $orgId = (int) Organization::owned($user->public_id)->value('id'); + $this->assertGreaterThan(0, $orgId); + + app(\App\Services\Qms\DemoSeeder::class)->resetForOwner($user->public_id); + + $org = Organization::query()->find($orgId); + $this->assertNotNull($org); + $this->assertTrue((bool) data_get($org->settings, 'onboarded')); + $this->assertTrue(app(\App\Services\Qms\OrganizationResolver::class)->isOnboarded($user)); + $this->assertSame(0, Branch::query()->where('organization_id', $orgId)->whereNull('deleted_at')->count()); } public function test_idempotent_without_reset(): void