feat(tenant): separate admin and storefront website types
This commit is contained in:
@@ -76,7 +76,7 @@ class WebsiteExtraController extends Controller
|
||||
$tenant = $user->tenant()->firstOrFail();
|
||||
|
||||
return $this->tenantInformationService->load($tenant, [
|
||||
'websiteType.extras',
|
||||
'storefrontWebsiteType.extras',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Domains\Tenant\Models;
|
||||
|
||||
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\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -31,16 +31,16 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
'footer_logo',
|
||||
'favicon_id',
|
||||
])]
|
||||
class WebsiteType extends Model
|
||||
class AdminWebsiteType extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'website_type';
|
||||
protected $table = 'admin_website_types';
|
||||
|
||||
/** @return HasMany<WebsiteTypeIntegration, $this> */
|
||||
/** @return HasMany<AdminWebsiteTypeIntegration, $this> */
|
||||
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 HasMany<WebsiteTypeExtra, $this>
|
||||
*/
|
||||
public function extras(): HasMany
|
||||
{
|
||||
return $this->hasMany(WebsiteTypeExtra::class, 'website_type_code', 'codigo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany<Tenant, $this>
|
||||
*/
|
||||
public function tenants(): HasMany
|
||||
{
|
||||
return $this->hasMany(Tenant::class, 'website_type_code', 'codigo');
|
||||
return $this->hasMany(Tenant::class, 'admin_website_type_code', 'codigo');
|
||||
}
|
||||
}
|
||||
28
app/Domains/Tenant/Models/StorefrontWebsiteType.php
Normal file
28
app/Domains/Tenant/Models/StorefrontWebsiteType.php
Normal 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');
|
||||
}
|
||||
}
|
||||
@@ -9,18 +9,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
#[Fillable([
|
||||
'website_type_code',
|
||||
'storefront_website_type_code',
|
||||
'codigo',
|
||||
'nombre',
|
||||
'descripcion',
|
||||
'is_required',
|
||||
'config_schema',
|
||||
])]
|
||||
class WebsiteTypeExtra extends Model
|
||||
class StorefrontWebsiteTypeExtra extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'website_type_extras';
|
||||
protected $table = 'storefront_website_type_extras';
|
||||
|
||||
/**
|
||||
* @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');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,8 @@ use Illuminate\Support\Facades\Schema;
|
||||
'favicon_id',
|
||||
'header_bg_image_id',
|
||||
'footer_bg_image_id',
|
||||
'website_type_code',
|
||||
'admin_website_type_code',
|
||||
'storefront_website_type_code',
|
||||
'search_product_layout',
|
||||
'search_group_layout',
|
||||
'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
|
||||
|
||||
@@ -48,11 +48,11 @@ class WebsiteExtra extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<WebsiteTypeExtra, $this>
|
||||
* @return BelongsTo<StorefrontWebsiteTypeExtra, $this>
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -127,12 +127,13 @@ class StoreTenantRequest extends FormRequest
|
||||
'min:0',
|
||||
'max:99.99',
|
||||
],
|
||||
'website_type_code' => [
|
||||
'storefront_website_type_code' => [
|
||||
'required_with:extras',
|
||||
'sometimes',
|
||||
'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')));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,18 @@ class UpdateTenantRequest extends FormRequest
|
||||
'min:0',
|
||||
'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.');
|
||||
}
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ class WebsiteExtrasResource extends JsonResource
|
||||
);
|
||||
|
||||
return [
|
||||
'website_type' => $this->websiteType ? [
|
||||
'codigo' => $this->websiteType->codigo,
|
||||
'nombre' => $this->websiteType->nombre,
|
||||
'storefront_website_type' => $this->storefrontWebsiteType ? [
|
||||
'codigo' => $this->storefrontWebsiteType->codigo,
|
||||
'nombre' => $this->storefrontWebsiteType->nombre,
|
||||
] : null,
|
||||
'definitions' => $this->websiteType?->extras
|
||||
'definitions' => $this->storefrontWebsiteType?->extras
|
||||
->mapWithKeys(fn ($definition) => [
|
||||
$definition->codigo => [
|
||||
'codigo' => $definition->codigo,
|
||||
|
||||
@@ -35,21 +35,19 @@ class TenantResource extends JsonResource
|
||||
'nombre' => $this->nombre,
|
||||
'dominio' => $this->dominio,
|
||||
'base_path' => $this->base_path,
|
||||
'site_title' => $this->site_title
|
||||
?? $this->websiteType?->site_title
|
||||
?? 'ShopitFront',
|
||||
'site_title' => $this->site_title ?? 'ShopitFront',
|
||||
'asset_url' => config('filesystems.disks.s3.url'),
|
||||
'address' => $this->address,
|
||||
'phone' => $this->phone,
|
||||
'favicon' => ($this->favicon ?? $this->websiteType?->favicon)
|
||||
?->getTemporaryUrl(1440),
|
||||
'favicon' => $this->favicon?->getTemporaryUrl(1440),
|
||||
'primary_color' => $this->primary_color,
|
||||
'secondary_color' => $this->secondary_color,
|
||||
'danger_color' => $this->danger_color,
|
||||
'success_color' => $this->success_color,
|
||||
'header_bg_color' => $this->header_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' => $this->whenLoaded('eventDates', fn () => $this->event_title === null
|
||||
? null
|
||||
|
||||
@@ -4,11 +4,11 @@ namespace App\Domains\Tenant\Services;
|
||||
|
||||
use App\Domains\Attachable\Models\Attachment;
|
||||
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\Str;
|
||||
|
||||
class WebsiteTypeService
|
||||
class AdminWebsiteTypeService
|
||||
{
|
||||
public function __construct(
|
||||
protected AttachmentService $attachmentService,
|
||||
@@ -19,9 +19,9 @@ class WebsiteTypeService
|
||||
*
|
||||
* @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> $values
|
||||
*/
|
||||
public function updateOrCreate(array $attributes, array $values = []): WebsiteType
|
||||
public function updateOrCreate(array $attributes, array $values = []): AdminWebsiteType
|
||||
{
|
||||
/** @var WebsiteType $websiteType */
|
||||
$websiteType = WebsiteType::query()->firstOrNew($attributes);
|
||||
/** @var AdminWebsiteType $websiteType */
|
||||
$websiteType = AdminWebsiteType::query()->firstOrNew($attributes);
|
||||
|
||||
return $this->save($websiteType, [...$attributes, ...$values]);
|
||||
}
|
||||
@@ -41,9 +41,9 @@ class WebsiteTypeService
|
||||
/**
|
||||
* @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 = [];
|
||||
|
||||
$attachmentFields = [
|
||||
@@ -68,7 +68,7 @@ class WebsiteTypeService
|
||||
if ($logo) {
|
||||
$attachment = is_string($logo) && Str::isUuid($logo)
|
||||
? Attachment::query()->where('key', $logo)->first()
|
||||
: $this->attachmentService->store($logo, 'website-types');
|
||||
: $this->attachmentService->store($logo, 'admin-website-types');
|
||||
}
|
||||
|
||||
$data[$attachmentField['column']] = $attachment?->id;
|
||||
@@ -82,7 +82,7 @@ class WebsiteTypeService
|
||||
&& $previousLogo->id !== $websiteType->site_logo
|
||||
&& $previousLogo->id !== $websiteType->footer_logo
|
||||
&& $previousLogo->id !== $websiteType->favicon_id
|
||||
&& ! $this->isReferencedByWebsiteType($previousLogo)
|
||||
&& ! $this->isReferencedByBrand($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 {
|
||||
$query
|
||||
->where('site_logo', $attachment->id)
|
||||
@@ -14,7 +14,6 @@ class TenantInformationService
|
||||
'headerLogo',
|
||||
'footerLogo',
|
||||
'favicon',
|
||||
'websiteType.favicon',
|
||||
'headerBackgroundImage',
|
||||
'footerBackgroundImage',
|
||||
'socialMedia',
|
||||
|
||||
@@ -9,8 +9,8 @@ use App\Domains\Shared\Rules\CroppedImageOrBase64Rule;
|
||||
use App\Domains\Shared\Rules\ImageOrBase64Rule;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Domains\Tenant\Models\WebsiteExtra;
|
||||
use App\Domains\Tenant\Models\WebsiteType;
|
||||
use App\Domains\Tenant\Models\WebsiteTypeExtra;
|
||||
use App\Domains\Tenant\Models\StorefrontWebsiteType;
|
||||
use App\Domains\Tenant\Models\StorefrontWebsiteTypeExtra;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -37,7 +37,7 @@ class WebsiteExtraService
|
||||
$definitions = $this->definitionsFor($websiteTypeCode);
|
||||
$allowedCodes = $definitions->pluck('codigo')->all();
|
||||
$hasRequiredExtras = $definitions->contains(
|
||||
fn (WebsiteTypeExtra $definition): bool => $definition->is_required
|
||||
fn (StorefrontWebsiteTypeExtra $definition): bool => $definition->is_required
|
||||
);
|
||||
|
||||
$rules = [
|
||||
@@ -95,11 +95,11 @@ class WebsiteExtraService
|
||||
return;
|
||||
}
|
||||
|
||||
$definitions = $this->definitionsFor((string) $tenant->website_type_code)
|
||||
$definitions = $this->definitionsFor((string) $tenant->storefront_website_type_code)
|
||||
->keyBy('codigo');
|
||||
|
||||
foreach ($extras as $name => $config) {
|
||||
/** @var WebsiteTypeExtra|null $definition */
|
||||
/** @var StorefrontWebsiteTypeExtra|null $definition */
|
||||
$definition = $definitions->get($name);
|
||||
|
||||
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()
|
||||
->where('website_type_code', $tenant->website_type_code)
|
||||
return StorefrontWebsiteTypeExtra::query()
|
||||
->where('storefront_website_type_code', $tenant->storefront_website_type_code)
|
||||
->where('codigo', $extraCode)
|
||||
->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, WebsiteTypeExtra>
|
||||
* @return Collection<int, StorefrontWebsiteTypeExtra>
|
||||
*/
|
||||
private function definitionsFor(string $websiteTypeCode): Collection
|
||||
{
|
||||
$websiteType = WebsiteType::query()
|
||||
$websiteType = StorefrontWebsiteType::query()
|
||||
->where('codigo', $websiteTypeCode)
|
||||
->with('extras')
|
||||
->first();
|
||||
@@ -252,7 +252,7 @@ class WebsiteExtraService
|
||||
|
||||
private function applyTransforms(
|
||||
Tenant $tenant,
|
||||
WebsiteTypeExtra $definition,
|
||||
StorefrontWebsiteTypeExtra $definition,
|
||||
mixed $config,
|
||||
string $requestRoot
|
||||
): mixed {
|
||||
@@ -318,7 +318,7 @@ class WebsiteExtraService
|
||||
*/
|
||||
private function transformValue(
|
||||
Tenant $tenant,
|
||||
WebsiteTypeExtra $definition,
|
||||
StorefrontWebsiteTypeExtra $definition,
|
||||
string $path,
|
||||
mixed $value,
|
||||
array $transform,
|
||||
|
||||
Reference in New Issue
Block a user