feat: Introduce client management and integration updates
- Added client_id field to StoreTenantRequest and UpdateTenantRequest for tenant management. - Updated TenantResource to include client_id in the response. - Created migration to establish clients table and link tenants to clients. - Migrated existing tenant integrations to client_integrations table. - Grouped specific tenants under a shared client (OnTicket) in a new migration. - Updated seeders to reflect new client structure and relationships. - Adjusted integration configurations to require client instead of tenant. - Added tests for client integration functionality and ensured existing tests reflect the new client structure.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('clients', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code')->unique();
|
||||
$table->string('name');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::table('tenants', function (Blueprint $table): void {
|
||||
$table->foreignId('client_id')->nullable()->after('id')->constrained('clients')->restrictOnDelete();
|
||||
});
|
||||
|
||||
DB::table('tenants')
|
||||
->select(['id', 'codigo', 'nombre', 'created_at', 'updated_at'])
|
||||
->orderBy('id')
|
||||
->each(function (object $tenant): void {
|
||||
$clientId = DB::table('clients')->insertGetId([
|
||||
'code' => $tenant->codigo,
|
||||
'name' => $tenant->nombre,
|
||||
'created_at' => $tenant->created_at ?? now(),
|
||||
'updated_at' => $tenant->updated_at ?? now(),
|
||||
]);
|
||||
|
||||
DB::table('tenants')->where('id', $tenant->id)->update(['client_id' => $clientId]);
|
||||
});
|
||||
|
||||
Schema::table('tenants', function (Blueprint $table): void {
|
||||
$table->unsignedBigInteger('client_id')->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('tenants', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('client_id');
|
||||
});
|
||||
|
||||
Schema::dropIfExists('clients');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('client_integrations', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('client_id')->constrained('clients')->cascadeOnDelete();
|
||||
$table->string('integration_code');
|
||||
$table->longText('integration_data')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('integration_code')
|
||||
->references('integration_code')
|
||||
->on('integrations')
|
||||
->cascadeOnDelete();
|
||||
$table->unique(['client_id', 'integration_code']);
|
||||
});
|
||||
|
||||
DB::table('tenant_integration')
|
||||
->join('tenants', 'tenants.codigo', '=', 'tenant_integration.tenant_code')
|
||||
->select([
|
||||
'tenants.client_id',
|
||||
'tenant_integration.integration_code',
|
||||
'tenant_integration.integration_data',
|
||||
'tenant_integration.created_at',
|
||||
'tenant_integration.updated_at',
|
||||
])
|
||||
->orderBy('tenant_integration.id')
|
||||
->each(function (object $configuration): void {
|
||||
DB::table('client_integrations')->updateOrInsert(
|
||||
[
|
||||
'client_id' => $configuration->client_id,
|
||||
'integration_code' => $configuration->integration_code,
|
||||
],
|
||||
[
|
||||
'integration_data' => $configuration->integration_data,
|
||||
'created_at' => $configuration->created_at,
|
||||
'updated_at' => $configuration->updated_at,
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
Schema::table('integrations', function (Blueprint $table): void {
|
||||
$table->boolean('requires_client_configuration')->default(true);
|
||||
});
|
||||
|
||||
DB::table('integrations')->update([
|
||||
'requires_client_configuration' => DB::raw('requires_tenant_configuration'),
|
||||
]);
|
||||
|
||||
Schema::table('integrations', function (Blueprint $table): void {
|
||||
$table->dropColumn('requires_tenant_configuration');
|
||||
});
|
||||
|
||||
Schema::dropIfExists('tenant_integration');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('integrations', function (Blueprint $table): void {
|
||||
$table->boolean('requires_tenant_configuration')->default(true);
|
||||
});
|
||||
|
||||
DB::table('integrations')->update([
|
||||
'requires_tenant_configuration' => DB::raw('requires_client_configuration'),
|
||||
]);
|
||||
|
||||
Schema::table('integrations', function (Blueprint $table): void {
|
||||
$table->dropColumn('requires_client_configuration');
|
||||
});
|
||||
|
||||
Schema::create('tenant_integration', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('integration_code');
|
||||
$table->string('tenant_code');
|
||||
$table->longText('integration_data')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('integration_code')->references('integration_code')->on('integrations')->cascadeOnDelete();
|
||||
$table->foreign('tenant_code')->references('codigo')->on('tenants')->cascadeOnDelete();
|
||||
$table->unique(['integration_code', 'tenant_code']);
|
||||
});
|
||||
|
||||
DB::table('client_integrations')
|
||||
->join('tenants', 'tenants.client_id', '=', 'client_integrations.client_id')
|
||||
->select([
|
||||
'tenants.codigo as tenant_code',
|
||||
'client_integrations.integration_code',
|
||||
'client_integrations.integration_data',
|
||||
'client_integrations.created_at',
|
||||
'client_integrations.updated_at',
|
||||
])
|
||||
->orderBy('client_integrations.id')
|
||||
->each(function (object $configuration): void {
|
||||
DB::table('tenant_integration')->insert((array) $configuration);
|
||||
});
|
||||
|
||||
Schema::dropIfExists('client_integrations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
private const CLIENT_CODE = 'onticket';
|
||||
|
||||
private const TENANT_CODES = [
|
||||
'fiesta_futbol_infantil',
|
||||
'desfile_pura_tendencia',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = now();
|
||||
|
||||
$clientId = DB::table('clients')->where('code', self::CLIENT_CODE)->value('id');
|
||||
|
||||
if ($clientId === null) {
|
||||
$clientId = DB::table('clients')->insertGetId([
|
||||
'code' => self::CLIENT_CODE,
|
||||
'name' => 'OnTicket',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('clients')->where('id', $clientId)->update([
|
||||
'name' => 'OnTicket',
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$tenants = DB::table('tenants')
|
||||
->whereIn('codigo', self::TENANT_CODES)
|
||||
->orderByRaw("CASE codigo WHEN 'fiesta_futbol_infantil' THEN 0 ELSE 1 END")
|
||||
->get(['codigo', 'client_id']);
|
||||
|
||||
foreach ($tenants as $tenant) {
|
||||
DB::table('client_integrations')
|
||||
->where('client_id', $tenant->client_id)
|
||||
->orderBy('id')
|
||||
->get()
|
||||
->each(function (object $integration) use ($clientId): void {
|
||||
DB::table('client_integrations')->insertOrIgnore([
|
||||
'client_id' => $clientId,
|
||||
'integration_code' => $integration->integration_code,
|
||||
'integration_data' => $integration->integration_data,
|
||||
'created_at' => $integration->created_at,
|
||||
'updated_at' => $integration->updated_at,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
DB::table('tenants')
|
||||
->whereIn('codigo', self::TENANT_CODES)
|
||||
->update(['client_id' => $clientId]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (self::TENANT_CODES as $tenantCode) {
|
||||
$tenant = DB::table('tenants')->where('codigo', $tenantCode)->first(['id']);
|
||||
|
||||
if (! $tenant) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('clients')->insertOrIgnore([
|
||||
'code' => $tenantCode,
|
||||
'name' => $tenantCode === 'fiesta_futbol_infantil'
|
||||
? 'Fiesta Fútbol Infantil'
|
||||
: 'Desfile Pura Tendencia',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$individualClientId = DB::table('clients')->where('code', $tenantCode)->value('id');
|
||||
$sharedClientId = DB::table('clients')->where('code', self::CLIENT_CODE)->value('id');
|
||||
|
||||
DB::table('client_integrations')
|
||||
->where('client_id', $sharedClientId)
|
||||
->orderBy('id')
|
||||
->get()
|
||||
->each(function (object $integration) use ($individualClientId): void {
|
||||
DB::table('client_integrations')->insertOrIgnore([
|
||||
'client_id' => $individualClientId,
|
||||
'integration_code' => $integration->integration_code,
|
||||
'integration_data' => $integration->integration_data,
|
||||
'created_at' => $integration->created_at,
|
||||
'updated_at' => $integration->updated_at,
|
||||
]);
|
||||
});
|
||||
|
||||
DB::table('tenants')->where('id', $tenant->id)->update([
|
||||
'client_id' => $individualClientId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user