feat(tenant): separate admin and storefront website types

This commit is contained in:
2026-09-17 14:25:46 -03:00
parent b9b5f8ec9c
commit 6bc784519f
31 changed files with 325 additions and 143 deletions

View File

@@ -2,21 +2,21 @@
namespace App\Domains\Bootstrap\Resources; namespace App\Domains\Bootstrap\Resources;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin array{website_type: WebsiteType} */ /** @mixin array{website_type: AdminWebsiteType} */
class AdminAppBootstrapResource extends JsonResource class AdminAppBootstrapResource extends JsonResource
{ {
/** @return array<string, mixed> */ /** @return array<string, mixed> */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {
/** @var WebsiteType $websiteType */ /** @var AdminWebsiteType $websiteType */
$websiteType = $this->resource['website_type']; $websiteType = $this->resource['website_type'];
return [ return [
'website_type_code' => $websiteType->codigo, 'admin_website_type_code' => $websiteType->codigo,
'site_title' => $websiteType->site_title, 'site_title' => $websiteType->site_title,
'primary_color' => $websiteType->primary_color, 'primary_color' => $websiteType->primary_color,
'secondary_color' => $websiteType->secondary_color, 'secondary_color' => $websiteType->secondary_color,

View File

@@ -2,15 +2,15 @@
namespace App\Domains\Bootstrap\Services; namespace App\Domains\Bootstrap\Services;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
class AdminAppBootstrapService class AdminAppBootstrapService
{ {
/** @return array{website_type: WebsiteType} */ /** @return array{website_type: AdminWebsiteType} */
public function get(string $domain): array public function get(string $domain): array
{ {
return [ return [
'website_type' => WebsiteType::query() 'website_type' => AdminWebsiteType::query()
->with(['siteLogo', 'footerLogo', 'favicon']) ->with(['siteLogo', 'footerLogo', 'favicon'])
->where('dominio', $domain) ->where('dominio', $domain)
->firstOrFail(), ->firstOrFail(),

View File

@@ -2,15 +2,15 @@
namespace App\Domains\Bootstrap\Services; namespace App\Domains\Bootstrap\Services;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
class ScannerBootstrapService class ScannerBootstrapService
{ {
/** @return array{website_type: WebsiteType} */ /** @return array{website_type: AdminWebsiteType} */
public function get(string $domain): array public function get(string $domain): array
{ {
return [ return [
'website_type' => WebsiteType::query() 'website_type' => AdminWebsiteType::query()
->with(['siteLogo', 'footerLogo', 'favicon']) ->with(['siteLogo', 'footerLogo', 'favicon'])
->where('scanner_domain', $domain) ->where('scanner_domain', $domain)
->firstOrFail(), ->firstOrFail(),

View File

@@ -58,7 +58,7 @@ class OnTicketFeaturedGroupController extends Controller
{ {
$tenant = $request->user()->tenant()->firstOrFail(); $tenant = $request->user()->tenant()->firstOrFail();
abort_unless($tenant->website_type_code === 'onticket', 404); abort_unless($tenant->storefront_website_type_code === 'onticket', 404);
return $tenant; return $tenant;
} }

View File

@@ -6,37 +6,37 @@ use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Requests\ConfigureIntegrationRequest; use App\Domains\Integration\Requests\ConfigureIntegrationRequest;
use App\Domains\Integration\Resources\IntegrationAssociationResource; use App\Domains\Integration\Resources\IntegrationAssociationResource;
use App\Domains\Integration\Services\IntegrationAssociationService; use App\Domains\Integration\Services\IntegrationAssociationService;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
class WebsiteTypeIntegrationController extends Controller class AdminWebsiteTypeIntegrationController extends Controller
{ {
public function __construct(private readonly IntegrationAssociationService $service) {} public function __construct(private readonly IntegrationAssociationService $service) {}
public function index(WebsiteType $websiteType) public function index(AdminWebsiteType $adminWebsiteType)
{ {
return IntegrationAssociationResource::collection($websiteType->integrations()->with('integrationInstance')->get()); return IntegrationAssociationResource::collection($adminWebsiteType->integrations()->with('integrationInstance')->get());
} }
public function show(WebsiteType $websiteType, string $integrationCode) public function show(AdminWebsiteType $adminWebsiteType, string $integrationCode)
{ {
return new IntegrationAssociationResource($websiteType->integrations()->with('integrationInstance')->where('integration_code', $integrationCode)->firstOrFail()); return new IntegrationAssociationResource($adminWebsiteType->integrations()->with('integrationInstance')->where('integration_code', $integrationCode)->firstOrFail());
} }
public function store(ConfigureIntegrationRequest $request, WebsiteType $websiteType, string $integrationCode) public function store(ConfigureIntegrationRequest $request, AdminWebsiteType $adminWebsiteType, string $integrationCode)
{ {
$integration = Integration::query()->where('integration_code', $integrationCode)->firstOrFail(); $integration = Integration::query()->where('integration_code', $integrationCode)->firstOrFail();
return new IntegrationAssociationResource($this->service->configure( return new IntegrationAssociationResource($this->service->configure(
$websiteType, $adminWebsiteType,
$integration, $integration,
$request->validated('integration_data'), $request->validated('integration_data'),
)); ));
} }
public function destroy(WebsiteType $websiteType, string $integrationCode) public function destroy(AdminWebsiteType $adminWebsiteType, string $integrationCode)
{ {
$this->service->detach($websiteType, $integrationCode); $this->service->detach($adminWebsiteType, $integrationCode);
return response()->noContent(); return response()->noContent();
} }

View File

@@ -2,18 +2,19 @@
namespace App\Domains\Integration\Models; namespace App\Domains\Integration\Models;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class WebsiteTypeIntegration extends Model class AdminWebsiteTypeIntegration extends Model
{ {
protected $fillable = ['website_type_code', 'integration_code', 'integration_instance_id']; protected $table = 'admin_website_type_integrations';
protected $fillable = ['admin_website_type_code', 'integration_code', 'integration_instance_id'];
/** @return BelongsTo<WebsiteType, $this> */ /** @return BelongsTo<AdminWebsiteType, $this> */
public function websiteType(): BelongsTo public function adminWebsiteType(): BelongsTo
{ {
return $this->belongsTo(WebsiteType::class, 'website_type_code', 'codigo'); return $this->belongsTo(AdminWebsiteType::class, 'admin_website_type_code', 'codigo');
} }
/** @return BelongsTo<Integration, $this> */ /** @return BelongsTo<Integration, $this> */

View File

@@ -34,9 +34,9 @@ class Integration extends Model
return $this->hasMany(ClientIntegration::class, 'integration_code', 'integration_code'); return $this->hasMany(ClientIntegration::class, 'integration_code', 'integration_code');
} }
/** @return HasMany<WebsiteTypeIntegration, $this> */ /** @return HasMany<AdminWebsiteTypeIntegration, $this> */
public function websiteTypeIntegrations(): HasMany public function websiteTypeIntegrations(): HasMany
{ {
return $this->hasMany(WebsiteTypeIntegration::class, 'integration_code', 'integration_code'); return $this->hasMany(AdminWebsiteTypeIntegration::class, 'integration_code', 'integration_code');
} }
} }

View File

@@ -33,9 +33,9 @@ class IntegrationInstance extends Model
return $this->hasMany(ClientIntegration::class); return $this->hasMany(ClientIntegration::class);
} }
/** @return HasMany<WebsiteTypeIntegration, $this> */ /** @return HasMany<AdminWebsiteTypeIntegration, $this> */
public function websiteTypeIntegrations(): HasMany public function websiteTypeIntegrations(): HasMany
{ {
return $this->hasMany(WebsiteTypeIntegration::class); return $this->hasMany(AdminWebsiteTypeIntegration::class);
} }
} }

View File

@@ -12,7 +12,7 @@ class IntegrationAssociationResource extends JsonResource
return [ return [
'id' => $this->id, 'id' => $this->id,
'client_id' => $this->when(isset($this->client_id), $this->client_id), 'client_id' => $this->when(isset($this->client_id), $this->client_id),
'website_type_code' => $this->when(isset($this->website_type_code), $this->website_type_code), 'admin_website_type_code' => $this->when(isset($this->admin_website_type_code), $this->admin_website_type_code),
'integration_code' => $this->integration_code, 'integration_code' => $this->integration_code,
'integration_instance_id' => $this->integration_instance_id, 'integration_instance_id' => $this->integration_instance_id,
'integration_instance' => new IntegrationInstanceResource($this->whenLoaded('integrationInstance')), 'integration_instance' => new IntegrationInstanceResource($this->whenLoaded('integrationInstance')),

View File

@@ -6,7 +6,7 @@ use App\Domains\Client\Models\Client;
use App\Domains\Integration\Models\ClientIntegration; use App\Domains\Integration\Models\ClientIntegration;
use App\Domains\Integration\Models\Integration; use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Models\IntegrationInstance; use App\Domains\Integration\Models\IntegrationInstance;
use App\Domains\Integration\Models\WebsiteTypeIntegration; use App\Domains\Integration\Models\AdminWebsiteTypeIntegration;
use App\Domains\Tenant\Models\Tenant; use App\Domains\Tenant\Models\Tenant;
use Exception; use Exception;
use Illuminate\Http\Client\PendingRequest; use Illuminate\Http\Client\PendingRequest;
@@ -111,9 +111,9 @@ abstract class BaseIntegrationService
->where('integration_code', $this->integrationCode) ->where('integration_code', $this->integrationCode)
->first()?->integrationInstance; ->first()?->integrationInstance;
if (! $this->integrationInstance && $this->tenant?->website_type_code) { if (! $this->integrationInstance && $this->tenant?->admin_website_type_code) {
$this->integrationInstance = WebsiteTypeIntegration::with('integrationInstance') $this->integrationInstance = AdminWebsiteTypeIntegration::with('integrationInstance')
->where('website_type_code', $this->tenant->website_type_code) ->where('admin_website_type_code', $this->tenant->admin_website_type_code)
->where('integration_code', $this->integrationCode) ->where('integration_code', $this->integrationCode)
->first()?->integrationInstance; ->first()?->integrationInstance;
} }

View File

@@ -6,15 +6,15 @@ use App\Domains\Client\Models\Client;
use App\Domains\Integration\Models\ClientIntegration; use App\Domains\Integration\Models\ClientIntegration;
use App\Domains\Integration\Models\Integration; use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Models\IntegrationInstance; use App\Domains\Integration\Models\IntegrationInstance;
use App\Domains\Integration\Models\WebsiteTypeIntegration; use App\Domains\Integration\Models\AdminWebsiteTypeIntegration;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
class IntegrationAssociationService class IntegrationAssociationService
{ {
public function configure(Client|WebsiteType $owner, Integration $integration, array $integrationData): ClientIntegration|WebsiteTypeIntegration public function configure(Client|AdminWebsiteType $owner, Integration $integration, array $integrationData): ClientIntegration|AdminWebsiteTypeIntegration
{ {
return DB::transaction(function () use ($owner, $integration, $integrationData): ClientIntegration|WebsiteTypeIntegration { return DB::transaction(function () use ($owner, $integration, $integrationData): ClientIntegration|AdminWebsiteTypeIntegration {
$instance = IntegrationInstance::create([ $instance = IntegrationInstance::create([
'integration_code' => $integration->integration_code, 'integration_code' => $integration->integration_code,
'name' => $integration->name.' / '.$this->ownerName($owner), 'name' => $integration->name.' / '.$this->ownerName($owner),
@@ -25,9 +25,9 @@ class IntegrationAssociationService
}); });
} }
public function associate(Client|WebsiteType $owner, string $code, IntegrationInstance $instance): ClientIntegration|WebsiteTypeIntegration public function associate(Client|AdminWebsiteType $owner, string $code, IntegrationInstance $instance): ClientIntegration|AdminWebsiteTypeIntegration
{ {
return DB::transaction(function () use ($owner, $code, $instance): ClientIntegration|WebsiteTypeIntegration { return DB::transaction(function () use ($owner, $code, $instance): ClientIntegration|AdminWebsiteTypeIntegration {
$association = $owner->integrations() $association = $owner->integrations()
->where('integration_code', $code) ->where('integration_code', $code)
->lockForUpdate() ->lockForUpdate()
@@ -62,7 +62,7 @@ class IntegrationAssociationService
}); });
} }
public function detach(Client|WebsiteType $owner, string $code): void public function detach(Client|AdminWebsiteType $owner, string $code): void
{ {
DB::transaction(function () use ($owner, $code): void { DB::transaction(function () use ($owner, $code): void {
$association = $owner->integrations() $association = $owner->integrations()
@@ -91,7 +91,7 @@ class IntegrationAssociationService
} }
} }
private function ownerName(Client|WebsiteType $owner): string private function ownerName(Client|AdminWebsiteType $owner): string
{ {
return $owner instanceof Client ? $owner->name : $owner->nombre; return $owner instanceof Client ? $owner->name : $owner->nombre;
} }

View File

@@ -4,7 +4,7 @@ namespace App\Domains\Integration\Services;
use App\Domains\Client\Models\Client; use App\Domains\Client\Models\Client;
use App\Domains\Tenant\Models\Tenant; use App\Domains\Tenant\Models\Tenant;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use Exception; use Exception;
use Illuminate\Contracts\Mail\Factory as MailFactory; use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailer; use Illuminate\Contracts\Mail\Mailer;
@@ -79,7 +79,7 @@ class MailService extends BaseIntegrationService
string|array $recipient, string|array $recipient,
string $subject, string $subject,
string $content, string $content,
Tenant|WebsiteType|null $brand = null, Tenant|AdminWebsiteType|null $brand = null,
array $attachments = [], array $attachments = [],
): void { ): void {
if (! $this->mailer || ! $this->tenant) { if (! $this->mailer || ! $this->tenant) {
@@ -97,7 +97,7 @@ class MailService extends BaseIntegrationService
BLADE, BLADE,
[ [
'branding' => $branding, 'branding' => $branding,
'headerLogoUrl' => $brand instanceof WebsiteType 'headerLogoUrl' => $brand instanceof AdminWebsiteType
? $brand->siteLogo?->getTemporaryUrl(1440) ? $brand->siteLogo?->getTemporaryUrl(1440)
: $brand->headerLogo?->getTemporaryUrl(1440), : $brand->headerLogo?->getTemporaryUrl(1440),
'footerLogoUrl' => $brand->footerLogo?->getTemporaryUrl(1440), 'footerLogoUrl' => $brand->footerLogo?->getTemporaryUrl(1440),
@@ -128,9 +128,9 @@ class MailService extends BaseIntegrationService
} }
/** @return array{name: string, primary_color: string, body_color: string, background_color: string, surface_color: string, header_bg_color: string, footer_bg_color: string} */ /** @return array{name: string, primary_color: string, body_color: string, background_color: string, surface_color: string, header_bg_color: string, footer_bg_color: string} */
private function brandingFor(Tenant|WebsiteType $brand): array private function brandingFor(Tenant|AdminWebsiteType $brand): array
{ {
if ($brand instanceof WebsiteType) { if ($brand instanceof AdminWebsiteType) {
$brand->loadMissing(['siteLogo', 'footerLogo']); $brand->loadMissing(['siteLogo', 'footerLogo']);
return [ return [

View File

@@ -2,16 +2,16 @@
use App\Domains\Integration\Controllers\ClientIntegrationController; use App\Domains\Integration\Controllers\ClientIntegrationController;
use App\Domains\Integration\Controllers\TelepagosWebhookController; use App\Domains\Integration\Controllers\TelepagosWebhookController;
use App\Domains\Integration\Controllers\WebsiteTypeIntegrationController; use App\Domains\Integration\Controllers\AdminWebsiteTypeIntegrationController;
use App\Domains\Integration\Models\Integration; use App\Domains\Integration\Models\Integration;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware(['auth:sanctum', 'can:manage,'.Integration::class])->group(function (): void { Route::middleware(['auth:sanctum', 'can:manage,'.Integration::class])->group(function (): void {
Route::prefix('website-types/{websiteType:codigo}/integrations')->group(function (): void { Route::prefix('admin-website-types/{adminWebsiteType:codigo}/integrations')->group(function (): void {
Route::get('/', [WebsiteTypeIntegrationController::class, 'index']); Route::get('/', [AdminWebsiteTypeIntegrationController::class, 'index']);
Route::get('/{integration_code}', [WebsiteTypeIntegrationController::class, 'show']); Route::get('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'show']);
Route::put('/{integration_code}', [WebsiteTypeIntegrationController::class, 'store']); Route::put('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'store']);
Route::delete('/{integration_code}', [WebsiteTypeIntegrationController::class, 'destroy']); Route::delete('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'destroy']);
}); });
Route::group(['prefix' => 'clients/{client}/integrations'], function () { Route::group(['prefix' => 'clients/{client}/integrations'], function () {

View File

@@ -31,7 +31,7 @@ class NotificationMailService
'user_id' => $userId, 'user_id' => $userId,
'tenant_code' => $tenantCode, 'tenant_code' => $tenantCode,
]; ];
$tenant = Tenant::query()->with('websiteType')->where('codigo', $tenantCode)->firstOrFail(); $tenant = Tenant::query()->where('codigo', $tenantCode)->firstOrFail();
$user = User::query()->findOrFail($userId); $user = User::query()->findOrFail($userId);
$this->sendIdempotently( $this->sendIdempotently(
@@ -41,7 +41,7 @@ class NotificationMailService
$context, $context,
$user->email, $user->email,
function () use ($user, $tenant, $tenantCode): array { function () use ($user, $tenant, $tenantCode): array {
$brand = $tenant->websiteType ?? $tenant; $brand = $tenant;
$tenantUrl = 'https://'.$tenant->dominio.$tenant->base_path; $tenantUrl = 'https://'.$tenant->dominio.$tenant->base_path;
$this->mailService $this->mailService
@@ -54,7 +54,7 @@ class NotificationMailService
); );
return [ return [
'brand_type' => $tenant->websiteType === null ? 'tenant' : 'website_type', 'brand_type' => 'tenant',
]; ];
}, },
); );
@@ -72,7 +72,7 @@ class NotificationMailService
]; ];
$tenant = Tenant::query() $tenant = Tenant::query()
->with('websiteType') ->with('adminWebsiteType')
->where('codigo', $tenantCode) ->where('codigo', $tenantCode)
->firstOrFail(); ->firstOrFail();
$attempt = ResetPasswordAttempt::query() $attempt = ResetPasswordAttempt::query()
@@ -97,8 +97,8 @@ class NotificationMailService
$attempt->user->email, $attempt->user->email,
function () use ($attempt, $tenant, $tenantCode, $channel): array { function () use ($attempt, $tenant, $tenantCode, $channel): array {
$recoveryDomain = match ($channel) { $recoveryDomain = match ($channel) {
PasswordResetRequested::CHANNEL_ADMINAPP => $tenant->websiteType?->dominio, PasswordResetRequested::CHANNEL_ADMINAPP => $tenant->adminWebsiteType?->dominio,
PasswordResetRequested::CHANNEL_SCANNER => $tenant->websiteType?->scanner_domain, PasswordResetRequested::CHANNEL_SCANNER => $tenant->adminWebsiteType?->scanner_domain,
default => $tenant->dominio, default => $tenant->dominio,
}; };
$recoveryBasePath = $channel === PasswordResetRequested::CHANNEL_STOREFRONT $recoveryBasePath = $channel === PasswordResetRequested::CHANNEL_STOREFRONT
@@ -115,7 +115,9 @@ class NotificationMailService
$recoveryUrl = $recoveryDomain === null $recoveryUrl = $recoveryDomain === null
? null ? null
: 'https://'.$recoveryDomain.$recoveryBasePath.'/recuperar-contrasena/codigo?'.http_build_query($recoveryQuery); : 'https://'.$recoveryDomain.$recoveryBasePath.'/recuperar-contrasena/codigo?'.http_build_query($recoveryQuery);
$brand = $tenant->websiteType ?? $tenant; $brand = $channel === PasswordResetRequested::CHANNEL_STOREFRONT
? $tenant
: ($tenant->adminWebsiteType ?? $tenant);
[$subject, $template] = match ($attempt->reason) { [$subject, $template] = match ($attempt->reason) {
ResetPasswordAttempt::REASON_STAFF_CREATED => [ ResetPasswordAttempt::REASON_STAFF_CREATED => [
@@ -291,7 +293,7 @@ class NotificationMailService
$newDate, $newDate,
$tickets, $tickets,
): array { ): array {
$brand = $purchase->tenant->websiteType ?? $purchase->tenant; $brand = $purchase->tenant;
$this->mailService $this->mailService
->forTenant($tenantCode) ->forTenant($tenantCode)
@@ -392,7 +394,7 @@ class NotificationMailService
$disabledTickets, $disabledTickets,
$activeTickets, $activeTickets,
): array { ): array {
$brand = $purchase->tenant->websiteType ?? $purchase->tenant; $brand = $purchase->tenant;
$this->mailService $this->mailService
->forTenant($tenantCode) ->forTenant($tenantCode)
@@ -419,7 +421,7 @@ class NotificationMailService
{ {
return Purchase::query() return Purchase::query()
->where('tenant_codigo', $tenantCode) ->where('tenant_codigo', $tenantCode)
->with(['tenant.websiteType', 'user']) ->with(['tenant', 'user'])
->find($purchaseId); ->find($purchaseId);
} }

View File

@@ -76,7 +76,7 @@ class WebsiteExtraController extends Controller
$tenant = $user->tenant()->firstOrFail(); $tenant = $user->tenant()->firstOrFail();
return $this->tenantInformationService->load($tenant, [ return $this->tenantInformationService->load($tenant, [
'websiteType.extras', 'storefrontWebsiteType.extras',
]); ]);
} }
} }

View File

@@ -3,7 +3,7 @@
namespace App\Domains\Tenant\Models; namespace App\Domains\Tenant\Models;
use App\Domains\Attachable\Models\Attachment; use App\Domains\Attachable\Models\Attachment;
use App\Domains\Integration\Models\WebsiteTypeIntegration; use App\Domains\Integration\Models\AdminWebsiteTypeIntegration;
use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -31,16 +31,16 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
'footer_logo', 'footer_logo',
'favicon_id', 'favicon_id',
])] ])]
class WebsiteType extends Model class AdminWebsiteType extends Model
{ {
use HasFactory; use HasFactory;
protected $table = 'website_type'; protected $table = 'admin_website_types';
/** @return HasMany<WebsiteTypeIntegration, $this> */ /** @return HasMany<AdminWebsiteTypeIntegration, $this> */
public function integrations(): HasMany public function integrations(): HasMany
{ {
return $this->hasMany(WebsiteTypeIntegration::class, 'website_type_code', 'codigo'); return $this->hasMany(AdminWebsiteTypeIntegration::class, 'admin_website_type_code', 'codigo');
} }
/** /**
@@ -67,19 +67,11 @@ class WebsiteType extends Model
return $this->belongsTo(Attachment::class, 'favicon_id'); return $this->belongsTo(Attachment::class, 'favicon_id');
} }
/**
* @return HasMany<WebsiteTypeExtra, $this>
*/
public function extras(): HasMany
{
return $this->hasMany(WebsiteTypeExtra::class, 'website_type_code', 'codigo');
}
/** /**
* @return HasMany<Tenant, $this> * @return HasMany<Tenant, $this>
*/ */
public function tenants(): HasMany public function tenants(): HasMany
{ {
return $this->hasMany(Tenant::class, 'website_type_code', 'codigo'); return $this->hasMany(Tenant::class, 'admin_website_type_code', 'codigo');
} }
} }

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Domains\Tenant\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable(['codigo', 'nombre'])]
class StorefrontWebsiteType extends Model
{
use HasFactory;
protected $table = 'storefront_website_types';
/** @return HasMany<StorefrontWebsiteTypeExtra, $this> */
public function extras(): HasMany
{
return $this->hasMany(StorefrontWebsiteTypeExtra::class, 'storefront_website_type_code', 'codigo');
}
/** @return HasMany<Tenant, $this> */
public function tenants(): HasMany
{
return $this->hasMany(Tenant::class, 'storefront_website_type_code', 'codigo');
}
}

View File

@@ -9,18 +9,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable([ #[Fillable([
'website_type_code', 'storefront_website_type_code',
'codigo', 'codigo',
'nombre', 'nombre',
'descripcion', 'descripcion',
'is_required', 'is_required',
'config_schema', 'config_schema',
])] ])]
class WebsiteTypeExtra extends Model class StorefrontWebsiteTypeExtra extends Model
{ {
use HasFactory; use HasFactory;
protected $table = 'website_type_extras'; protected $table = 'storefront_website_type_extras';
/** /**
* @return array<string, string> * @return array<string, string>
@@ -34,11 +34,11 @@ class WebsiteTypeExtra extends Model
} }
/** /**
* @return BelongsTo<WebsiteType, $this> * @return BelongsTo<StorefrontWebsiteType, $this>
*/ */
public function websiteType(): BelongsTo public function storefrontWebsiteType(): BelongsTo
{ {
return $this->belongsTo(WebsiteType::class, 'website_type_code', 'codigo'); return $this->belongsTo(StorefrontWebsiteType::class, 'storefront_website_type_code', 'codigo');
} }
/** /**

View File

@@ -42,7 +42,8 @@ use Illuminate\Support\Facades\Schema;
'favicon_id', 'favicon_id',
'header_bg_image_id', 'header_bg_image_id',
'footer_bg_image_id', 'footer_bg_image_id',
'website_type_code', 'admin_website_type_code',
'storefront_website_type_code',
'search_product_layout', 'search_product_layout',
'search_group_layout', 'search_group_layout',
'search_items_per_page', 'search_items_per_page',
@@ -210,11 +211,17 @@ class Tenant extends Model
} }
/** /**
* @return BelongsTo<WebsiteType, $this> * @return BelongsTo<AdminWebsiteType, $this>
*/ */
public function websiteType(): BelongsTo public function adminWebsiteType(): BelongsTo
{ {
return $this->belongsTo(WebsiteType::class, 'website_type_code', 'codigo'); return $this->belongsTo(AdminWebsiteType::class, 'admin_website_type_code', 'codigo');
}
/** @return BelongsTo<StorefrontWebsiteType, $this> */
public function storefrontWebsiteType(): BelongsTo
{
return $this->belongsTo(StorefrontWebsiteType::class, 'storefront_website_type_code', 'codigo');
} }
public function catalogItems(): HasMany public function catalogItems(): HasMany

View File

@@ -48,11 +48,11 @@ class WebsiteExtra extends Model
} }
/** /**
* @return BelongsTo<WebsiteTypeExtra, $this> * @return BelongsTo<StorefrontWebsiteTypeExtra, $this>
*/ */
public function websiteTypeExtra(): BelongsTo public function websiteTypeExtra(): BelongsTo
{ {
return $this->belongsTo(WebsiteTypeExtra::class, 'website_type_extra_id'); return $this->belongsTo(StorefrontWebsiteTypeExtra::class, 'website_type_extra_id');
} }
public function setResolvedConfig(mixed $config): self public function setResolvedConfig(mixed $config): self

View File

@@ -127,12 +127,13 @@ class StoreTenantRequest extends FormRequest
'min:0', 'min:0',
'max:99.99', 'max:99.99',
], ],
'website_type_code' => [ 'storefront_website_type_code' => [
'required_with:extras', 'required_with:extras',
'sometimes', 'sometimes',
'string', 'string',
Rule::exists('website_type', 'codigo'), Rule::exists('storefront_website_types', 'codigo'),
], ],
], app(WebsiteExtraService::class)->requestRules($this->input('website_type_code'))); 'admin_website_type_code' => ['sometimes', 'nullable', 'string', Rule::exists('admin_website_types', 'codigo')],
], app(WebsiteExtraService::class)->requestRules($this->input('storefront_website_type_code')));
} }
} }

View File

@@ -148,6 +148,18 @@ class UpdateTenantRequest extends FormRequest
'min:0', 'min:0',
'max:99.99', 'max:99.99',
], ],
'admin_website_type_code' => ['sometimes', 'nullable', 'string', Rule::exists('admin_website_types', 'codigo')],
'storefront_website_type_code' => [
'sometimes',
'nullable',
'string',
Rule::exists('storefront_website_types', 'codigo'),
function (string $attribute, mixed $value, Closure $fail) use ($tenant): void {
if ($tenant && $value !== $tenant->storefront_website_type_code && $tenant->websiteExtras()->exists()) {
$fail('The storefront website type cannot be changed while the tenant has extras.');
}
},
],
]; ];
} }
} }

View File

@@ -23,11 +23,11 @@ class WebsiteExtrasResource extends JsonResource
); );
return [ return [
'website_type' => $this->websiteType ? [ 'storefront_website_type' => $this->storefrontWebsiteType ? [
'codigo' => $this->websiteType->codigo, 'codigo' => $this->storefrontWebsiteType->codigo,
'nombre' => $this->websiteType->nombre, 'nombre' => $this->storefrontWebsiteType->nombre,
] : null, ] : null,
'definitions' => $this->websiteType?->extras 'definitions' => $this->storefrontWebsiteType?->extras
->mapWithKeys(fn ($definition) => [ ->mapWithKeys(fn ($definition) => [
$definition->codigo => [ $definition->codigo => [
'codigo' => $definition->codigo, 'codigo' => $definition->codigo,

View File

@@ -35,21 +35,19 @@ class TenantResource extends JsonResource
'nombre' => $this->nombre, 'nombre' => $this->nombre,
'dominio' => $this->dominio, 'dominio' => $this->dominio,
'base_path' => $this->base_path, 'base_path' => $this->base_path,
'site_title' => $this->site_title 'site_title' => $this->site_title ?? 'ShopitFront',
?? $this->websiteType?->site_title
?? 'ShopitFront',
'asset_url' => config('filesystems.disks.s3.url'), 'asset_url' => config('filesystems.disks.s3.url'),
'address' => $this->address, 'address' => $this->address,
'phone' => $this->phone, 'phone' => $this->phone,
'favicon' => ($this->favicon ?? $this->websiteType?->favicon) 'favicon' => $this->favicon?->getTemporaryUrl(1440),
?->getTemporaryUrl(1440),
'primary_color' => $this->primary_color, 'primary_color' => $this->primary_color,
'secondary_color' => $this->secondary_color, 'secondary_color' => $this->secondary_color,
'danger_color' => $this->danger_color, 'danger_color' => $this->danger_color,
'success_color' => $this->success_color, 'success_color' => $this->success_color,
'header_bg_color' => $this->header_bg_color, 'header_bg_color' => $this->header_bg_color,
'footer_bg_color' => $this->footer_bg_color, 'footer_bg_color' => $this->footer_bg_color,
'website_type_code' => $this->website_type_code, 'admin_website_type_code' => $this->admin_website_type_code,
'storefront_website_type_code' => $this->storefront_website_type_code,
'event_date_text' => $this->event_date_text, 'event_date_text' => $this->event_date_text,
'event' => $this->whenLoaded('eventDates', fn () => $this->event_title === null 'event' => $this->whenLoaded('eventDates', fn () => $this->event_title === null
? null ? null

View File

@@ -4,11 +4,11 @@ namespace App\Domains\Tenant\Services;
use App\Domains\Attachable\Models\Attachment; use App\Domains\Attachable\Models\Attachment;
use App\Domains\Attachable\Services\AttachmentService; use App\Domains\Attachable\Services\AttachmentService;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class WebsiteTypeService class AdminWebsiteTypeService
{ {
public function __construct( public function __construct(
protected AttachmentService $attachmentService, protected AttachmentService $attachmentService,
@@ -19,9 +19,9 @@ class WebsiteTypeService
* *
* @param array<string, mixed> $data * @param array<string, mixed> $data
*/ */
public function create(array $data): WebsiteType public function create(array $data): AdminWebsiteType
{ {
return $this->save(new WebsiteType, $data); return $this->save(new AdminWebsiteType, $data);
} }
/** /**
@@ -30,10 +30,10 @@ class WebsiteTypeService
* @param array<string, mixed> $attributes * @param array<string, mixed> $attributes
* @param array<string, mixed> $values * @param array<string, mixed> $values
*/ */
public function updateOrCreate(array $attributes, array $values = []): WebsiteType public function updateOrCreate(array $attributes, array $values = []): AdminWebsiteType
{ {
/** @var WebsiteType $websiteType */ /** @var AdminWebsiteType $websiteType */
$websiteType = WebsiteType::query()->firstOrNew($attributes); $websiteType = AdminWebsiteType::query()->firstOrNew($attributes);
return $this->save($websiteType, [...$attributes, ...$values]); return $this->save($websiteType, [...$attributes, ...$values]);
} }
@@ -41,9 +41,9 @@ class WebsiteTypeService
/** /**
* @param array<string, mixed> $data * @param array<string, mixed> $data
*/ */
private function save(WebsiteType $websiteType, array $data): WebsiteType private function save(AdminWebsiteType $websiteType, array $data): AdminWebsiteType
{ {
return DB::transaction(function () use ($websiteType, $data): WebsiteType { return DB::transaction(function () use ($websiteType, $data): AdminWebsiteType {
$previousLogos = []; $previousLogos = [];
$attachmentFields = [ $attachmentFields = [
@@ -68,7 +68,7 @@ class WebsiteTypeService
if ($logo) { if ($logo) {
$attachment = is_string($logo) && Str::isUuid($logo) $attachment = is_string($logo) && Str::isUuid($logo)
? Attachment::query()->where('key', $logo)->first() ? Attachment::query()->where('key', $logo)->first()
: $this->attachmentService->store($logo, 'website-types'); : $this->attachmentService->store($logo, 'admin-website-types');
} }
$data[$attachmentField['column']] = $attachment?->id; $data[$attachmentField['column']] = $attachment?->id;
@@ -82,7 +82,7 @@ class WebsiteTypeService
&& $previousLogo->id !== $websiteType->site_logo && $previousLogo->id !== $websiteType->site_logo
&& $previousLogo->id !== $websiteType->footer_logo && $previousLogo->id !== $websiteType->footer_logo
&& $previousLogo->id !== $websiteType->favicon_id && $previousLogo->id !== $websiteType->favicon_id
&& ! $this->isReferencedByWebsiteType($previousLogo) && ! $this->isReferencedByBrand($previousLogo)
) { ) {
$this->attachmentService->delete($previousLogo); $this->attachmentService->delete($previousLogo);
} }
@@ -92,9 +92,10 @@ class WebsiteTypeService
}); });
} }
private function isReferencedByWebsiteType(Attachment $attachment): bool private function isReferencedByBrand(Attachment $attachment): bool
{ {
return WebsiteType::query() return Tenant::query()->where('favicon_id', $attachment->id)->exists()
|| AdminWebsiteType::query()
->where(function ($query) use ($attachment): void { ->where(function ($query) use ($attachment): void {
$query $query
->where('site_logo', $attachment->id) ->where('site_logo', $attachment->id)

View File

@@ -14,7 +14,6 @@ class TenantInformationService
'headerLogo', 'headerLogo',
'footerLogo', 'footerLogo',
'favicon', 'favicon',
'websiteType.favicon',
'headerBackgroundImage', 'headerBackgroundImage',
'footerBackgroundImage', 'footerBackgroundImage',
'socialMedia', 'socialMedia',

View File

@@ -9,8 +9,8 @@ use App\Domains\Shared\Rules\CroppedImageOrBase64Rule;
use App\Domains\Shared\Rules\ImageOrBase64Rule; use App\Domains\Shared\Rules\ImageOrBase64Rule;
use App\Domains\Tenant\Models\Tenant; use App\Domains\Tenant\Models\Tenant;
use App\Domains\Tenant\Models\WebsiteExtra; use App\Domains\Tenant\Models\WebsiteExtra;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\StorefrontWebsiteType;
use App\Domains\Tenant\Models\WebsiteTypeExtra; use App\Domains\Tenant\Models\StorefrontWebsiteTypeExtra;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@@ -37,7 +37,7 @@ class WebsiteExtraService
$definitions = $this->definitionsFor($websiteTypeCode); $definitions = $this->definitionsFor($websiteTypeCode);
$allowedCodes = $definitions->pluck('codigo')->all(); $allowedCodes = $definitions->pluck('codigo')->all();
$hasRequiredExtras = $definitions->contains( $hasRequiredExtras = $definitions->contains(
fn (WebsiteTypeExtra $definition): bool => $definition->is_required fn (StorefrontWebsiteTypeExtra $definition): bool => $definition->is_required
); );
$rules = [ $rules = [
@@ -95,11 +95,11 @@ class WebsiteExtraService
return; return;
} }
$definitions = $this->definitionsFor((string) $tenant->website_type_code) $definitions = $this->definitionsFor((string) $tenant->storefront_website_type_code)
->keyBy('codigo'); ->keyBy('codigo');
foreach ($extras as $name => $config) { foreach ($extras as $name => $config) {
/** @var WebsiteTypeExtra|null $definition */ /** @var StorefrontWebsiteTypeExtra|null $definition */
$definition = $definitions->get($name); $definition = $definitions->get($name);
if (! $definition) { if (! $definition) {
@@ -193,20 +193,20 @@ class WebsiteExtraService
}); });
} }
public function definitionForTenant(Tenant $tenant, string $extraCode): WebsiteTypeExtra public function definitionForTenant(Tenant $tenant, string $extraCode): StorefrontWebsiteTypeExtra
{ {
return WebsiteTypeExtra::query() return StorefrontWebsiteTypeExtra::query()
->where('website_type_code', $tenant->website_type_code) ->where('storefront_website_type_code', $tenant->storefront_website_type_code)
->where('codigo', $extraCode) ->where('codigo', $extraCode)
->firstOrFail(); ->firstOrFail();
} }
/** /**
* @return Collection<int, WebsiteTypeExtra> * @return Collection<int, StorefrontWebsiteTypeExtra>
*/ */
private function definitionsFor(string $websiteTypeCode): Collection private function definitionsFor(string $websiteTypeCode): Collection
{ {
$websiteType = WebsiteType::query() $websiteType = StorefrontWebsiteType::query()
->where('codigo', $websiteTypeCode) ->where('codigo', $websiteTypeCode)
->with('extras') ->with('extras')
->first(); ->first();
@@ -252,7 +252,7 @@ class WebsiteExtraService
private function applyTransforms( private function applyTransforms(
Tenant $tenant, Tenant $tenant,
WebsiteTypeExtra $definition, StorefrontWebsiteTypeExtra $definition,
mixed $config, mixed $config,
string $requestRoot string $requestRoot
): mixed { ): mixed {
@@ -318,7 +318,7 @@ class WebsiteExtraService
*/ */
private function transformValue( private function transformValue(
Tenant $tenant, Tenant $tenant,
WebsiteTypeExtra $definition, StorefrontWebsiteTypeExtra $definition,
string $path, string $path,
mixed $value, mixed $value,
array $transform, array $transform,

View File

@@ -0,0 +1,132 @@
<?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('storefront_website_types', function (Blueprint $table): void {
$table->id();
$table->string('codigo')->unique();
$table->string('nombre');
$table->timestamps();
});
DB::table('website_type')->orderBy('id')->chunk(100, function ($types): void {
foreach ($types as $type) {
DB::table('storefront_website_types')->insert([
'id' => $type->id,
'codigo' => $type->codigo,
'nombre' => $type->nombre,
'created_at' => $type->created_at,
'updated_at' => $type->updated_at,
]);
}
});
Schema::table('tenants', function (Blueprint $table): void {
$table->string('storefront_website_type_code')->nullable();
});
DB::table('tenants')->orderBy('id')->chunk(100, function ($tenants): void {
foreach ($tenants as $tenant) {
$type = $tenant->website_type_code
? DB::table('website_type')->where('codigo', $tenant->website_type_code)->first()
: null;
DB::table('tenants')->where('id', $tenant->id)->update([
'storefront_website_type_code' => $tenant->website_type_code,
'site_title' => $tenant->site_title ?? $type?->site_title,
'favicon_id' => $tenant->favicon_id ?? $type?->favicon_id,
]);
}
});
if (DB::getDriverName() !== 'sqlite') {
Schema::table('tenants', fn (Blueprint $table) => $table->dropForeign(['website_type_code']));
Schema::table('website_type_extras', fn (Blueprint $table) => $table->dropForeign(['website_type_code']));
Schema::table('website_type_integrations', fn (Blueprint $table) => $table->dropForeign(['website_type_code']));
}
Schema::rename('website_type', 'admin_website_types');
Schema::rename('website_type_extras', 'storefront_website_type_extras');
Schema::rename('website_type_integrations', 'admin_website_type_integrations');
Schema::table('tenants', fn (Blueprint $table) => $table->renameColumn('website_type_code', 'admin_website_type_code'));
Schema::table('storefront_website_type_extras', fn (Blueprint $table) => $table->renameColumn('website_type_code', 'storefront_website_type_code'));
Schema::table('admin_website_type_integrations', fn (Blueprint $table) => $table->renameColumn('website_type_code', 'admin_website_type_code'));
if (DB::getDriverName() === 'sqlite') {
Schema::disableForeignKeyConstraints();
Schema::create('storefront_website_type_extras_rebuilt', function (Blueprint $table): void {
$table->id();
$table->string('storefront_website_type_code');
$table->foreign('storefront_website_type_code')->references('codigo')->on('storefront_website_types')->cascadeOnUpdate()->cascadeOnDelete();
$table->string('codigo')->nullable();
$table->string('nombre');
$table->text('descripcion');
$table->boolean('is_required')->default(false);
$table->json('config_schema');
$table->timestamps();
$table->unique(['storefront_website_type_code', 'codigo']);
});
DB::table('storefront_website_type_extras')->orderBy('id')->chunk(100, function ($extras): void {
foreach ($extras as $extra) {
DB::table('storefront_website_type_extras_rebuilt')->insert((array) $extra);
}
});
Schema::drop('storefront_website_type_extras');
Schema::rename('storefront_website_type_extras_rebuilt', 'storefront_website_type_extras');
Schema::enableForeignKeyConstraints();
}
Schema::table('tenants', function (Blueprint $table): void {
if (DB::getDriverName() !== 'sqlite') {
$table->foreign('admin_website_type_code')->references('codigo')->on('admin_website_types')->cascadeOnUpdate()->nullOnDelete();
}
$table->foreign('storefront_website_type_code')->references('codigo')->on('storefront_website_types')->cascadeOnUpdate()->nullOnDelete();
});
if (DB::getDriverName() !== 'sqlite') {
Schema::table('storefront_website_type_extras', function (Blueprint $table): void {
$table->foreign('storefront_website_type_code')->references('codigo')->on('storefront_website_types')->cascadeOnUpdate()->cascadeOnDelete();
});
Schema::table('admin_website_type_integrations', function (Blueprint $table): void {
$table->foreign('admin_website_type_code')->references('codigo')->on('admin_website_types')->cascadeOnDelete();
});
}
}
public function down(): void
{
if (DB::getDriverName() === 'sqlite') {
throw new RuntimeException('SQLite rollback is unsupported for this foreign-key refactor. Recreate the test database instead.');
}
Schema::table('tenants', function (Blueprint $table): void {
$table->dropForeign(['admin_website_type_code']);
$table->dropForeign(['storefront_website_type_code']);
});
Schema::table('storefront_website_type_extras', fn (Blueprint $table) => $table->dropForeign(['storefront_website_type_code']));
Schema::table('admin_website_type_integrations', fn (Blueprint $table) => $table->dropForeign(['admin_website_type_code']));
Schema::table('tenants', fn (Blueprint $table) => $table->renameColumn('admin_website_type_code', 'website_type_code'));
Schema::table('storefront_website_type_extras', fn (Blueprint $table) => $table->renameColumn('storefront_website_type_code', 'website_type_code'));
Schema::table('admin_website_type_integrations', fn (Blueprint $table) => $table->renameColumn('admin_website_type_code', 'website_type_code'));
Schema::rename('admin_website_types', 'website_type');
Schema::rename('storefront_website_type_extras', 'website_type_extras');
Schema::rename('admin_website_type_integrations', 'website_type_integrations');
Schema::table('tenants', function (Blueprint $table): void {
$table->foreign('website_type_code')->references('codigo')->on('website_type')->cascadeOnUpdate()->nullOnDelete();
$table->dropColumn('storefront_website_type_code');
});
Schema::table('website_type_extras', fn (Blueprint $table) => $table->foreign('website_type_code')->references('codigo')->on('website_type')->cascadeOnUpdate()->cascadeOnDelete());
Schema::table('website_type_integrations', fn (Blueprint $table) => $table->foreign('website_type_code')->references('codigo')->on('website_type')->cascadeOnDelete());
Schema::dropIfExists('storefront_website_types');
}
};

View File

@@ -78,7 +78,8 @@ class DesfilePuraTendenciaSeeder extends Seeder
'checkout_editing_policy' => 'disabled', 'checkout_editing_policy' => 'disabled',
'display_cart_item_images' => false, 'display_cart_item_images' => false,
'scanner_category_validation_enabled' => false, 'scanner_category_validation_enabled' => false,
'website_type_code' => 'onticket', 'admin_website_type_code' => 'onticket',
'storefront_website_type_code' => 'onticket',
'header_logo' => $this->uploadedImage( 'header_logo' => $this->uploadedImage(
'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_header.png', 'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_header.png',
'desfile_pura_tendencia_header.png', 'desfile_pura_tendencia_header.png',

View File

@@ -6,7 +6,7 @@ use App\Domains\Attachable\Models\Attachment;
use App\Domains\Attachable\Services\AttachmentService; use App\Domains\Attachable\Services\AttachmentService;
use App\Domains\Client\Models\Client; use App\Domains\Client\Models\Client;
use App\Domains\Tenant\Models\Tenant; use App\Domains\Tenant\Models\Tenant;
use App\Domains\Tenant\Models\WebsiteType; use App\Domains\Tenant\Models\AdminWebsiteType;
use App\Domains\Tenant\Services\TenantService; use App\Domains\Tenant\Services\TenantService;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
@@ -56,7 +56,7 @@ class TenantSeeder extends Seeder
['name' => 'OnTicket'], ['name' => 'OnTicket'],
); );
$onTicketType = WebsiteType::query()->where('codigo', 'onticket')->firstOrFail(); $onTicketType = AdminWebsiteType::query()->where('codigo', 'onticket')->firstOrFail();
$onTicketTenant = Tenant::query()->where('codigo', 'onticket')->first(); $onTicketTenant = Tenant::query()->where('codigo', 'onticket')->first();
@@ -75,7 +75,8 @@ class TenantSeeder extends Seeder
'footer_bg_color' => $onTicketType->surface_color, 'footer_bg_color' => $onTicketType->surface_color,
'display_categories' => false, 'display_categories' => false,
'display_seach_bar' => false, 'display_seach_bar' => false,
'website_type_code' => $onTicketType->codigo, 'admin_website_type_code' => $onTicketType->codigo,
'storefront_website_type_code' => $onTicketType->codigo,
'header_logo' => $this->uploadedImage( 'header_logo' => $this->uploadedImage(
'images/tennants/onticket/onticket_logo.png', 'images/tennants/onticket/onticket_logo.png',
'onticket_logo.png', 'onticket_logo.png',
@@ -127,7 +128,8 @@ class TenantSeeder extends Seeder
'header_logo' => $this->uploadedImage('images/tennants/sonder/sonder_header.png', 'sonder_header.png'), 'header_logo' => $this->uploadedImage('images/tennants/sonder/sonder_header.png', 'sonder_header.png'),
'footer_logo' => $this->uploadedImage('images/tennants/sonder/sonder_footer.png', 'sonder_footer.png'), 'footer_logo' => $this->uploadedImage('images/tennants/sonder/sonder_footer.png', 'sonder_footer.png'),
'social_media' => self::SOCIAL_MEDIA, 'social_media' => self::SOCIAL_MEDIA,
'website_type_code' => 'shopit', 'admin_website_type_code' => 'shopit',
'storefront_website_type_code' => 'shopit',
'extras' => [ 'extras' => [
'carousel' => [ 'carousel' => [
$this->uploadedImage( $this->uploadedImage(
@@ -195,7 +197,8 @@ class TenantSeeder extends Seeder
'futbol_infantil_favicon.png', 'futbol_infantil_favicon.png',
), ),
'social_media' => self::SOCIAL_MEDIA, 'social_media' => self::SOCIAL_MEDIA,
'website_type_code' => 'onticket', 'admin_website_type_code' => 'onticket',
'storefront_website_type_code' => 'onticket',
'extras' => [ 'extras' => [
'heroConfig' => [ 'heroConfig' => [
'title_html' => '<h1>Fiesta Fútbol Infantil</h1>', 'title_html' => '<h1>Fiesta Fútbol Infantil</h1>',

View File

@@ -2,7 +2,8 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Domains\Tenant\Services\WebsiteTypeService; use App\Domains\Tenant\Services\AdminWebsiteTypeService;
use App\Domains\Tenant\Models\StorefrontWebsiteType;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
use RuntimeException; use RuntimeException;
@@ -22,7 +23,7 @@ class WebsiteTypeSeeder extends Seeder
'border_color' => '#EAEAEA', 'border_color' => '#EAEAEA',
]; ];
public function __construct(private readonly WebsiteTypeService $websiteTypeService) {} public function __construct(private readonly AdminWebsiteTypeService $websiteTypeService) {}
public function run(): void public function run(): void
{ {
@@ -40,7 +41,9 @@ class WebsiteTypeSeeder extends Seeder
], ],
); );
$shopIt->extras()->updateOrCreate( $shopItStorefront = StorefrontWebsiteType::query()->updateOrCreate(['codigo' => 'shopit'], ['nombre' => 'ShopIt']);
$shopItStorefront->extras()->updateOrCreate(
['codigo' => 'carousel'], ['codigo' => 'carousel'],
[ [
'nombre' => 'Carrusel principal', 'nombre' => 'Carrusel principal',
@@ -75,7 +78,9 @@ class WebsiteTypeSeeder extends Seeder
], ],
); );
$onTicket->extras()->updateOrCreate( $onTicketStorefront = StorefrontWebsiteType::query()->updateOrCreate(['codigo' => 'onticket'], ['nombre' => 'OnTicket']);
$onTicketStorefront->extras()->updateOrCreate(
['codigo' => 'heroConfig'], ['codigo' => 'heroConfig'],
[ [
'nombre' => 'Configuración del hero', 'nombre' => 'Configuración del hero',
@@ -100,7 +105,7 @@ class WebsiteTypeSeeder extends Seeder
], ],
); );
$onTicket->extras()->updateOrCreate( $onTicketStorefront->extras()->updateOrCreate(
['codigo' => 'eventConfig'], ['codigo' => 'eventConfig'],
[ [
'nombre' => 'Información del evento', 'nombre' => 'Información del evento',
@@ -127,7 +132,7 @@ class WebsiteTypeSeeder extends Seeder
], ],
); );
$onTicket->extras()->updateOrCreate( $onTicketStorefront->extras()->updateOrCreate(
['codigo' => 'additionalInfoConfig'], ['codigo' => 'additionalInfoConfig'],
[ [
'nombre' => 'Información adicional', 'nombre' => 'Información adicional',