feat(tenant): provision Desfile Pura Tendencia and extend tenant customization
- Add Desfile Pura Tendencia tenant migration with catalog, variants, event, menus and assets - Support tenant header/footer background images - Add configurable cart visibility - Update tenant seeding and API resources - Add migration and bootstrap feature tests
This commit is contained in:
@@ -29,12 +29,15 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
'footer_bg_color',
|
||||
'header_logo_id',
|
||||
'footer_logo_id',
|
||||
'header_bg_image_id',
|
||||
'footer_bg_image_id',
|
||||
'website_type_code',
|
||||
'search_product_layout',
|
||||
'search_group_layout',
|
||||
'search_items_per_page',
|
||||
'display_categories',
|
||||
'display_seach_bar',
|
||||
'display_cart',
|
||||
'event_title',
|
||||
'event_location',
|
||||
'event_date_text',
|
||||
@@ -49,6 +52,7 @@ class Tenant extends Model
|
||||
'search_items_per_page' => 12,
|
||||
'display_categories' => true,
|
||||
'display_seach_bar' => true,
|
||||
'display_cart' => true,
|
||||
];
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
@@ -69,6 +73,7 @@ class Tenant extends Model
|
||||
'search_items_per_page' => 'integer',
|
||||
'display_categories' => 'boolean',
|
||||
'display_seach_bar' => 'boolean',
|
||||
'display_cart' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -88,6 +93,22 @@ class Tenant extends Model
|
||||
return $this->belongsTo(Attachment::class, 'footer_logo_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Attachment, $this>
|
||||
*/
|
||||
public function headerBackgroundImage(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Attachment::class, 'header_bg_image_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Attachment, $this>
|
||||
*/
|
||||
public function footerBackgroundImage(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Attachment::class, 'footer_bg_image_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<WebsiteType, $this>
|
||||
*/
|
||||
|
||||
@@ -63,6 +63,8 @@ class StoreTenantRequest extends FormRequest
|
||||
'footer_bg_color' => ['required', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'],
|
||||
'header_logo' => $logoRule,
|
||||
'footer_logo' => $logoRule,
|
||||
'header_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule],
|
||||
'footer_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule],
|
||||
'social_media' => ['sometimes', 'array'],
|
||||
'social_media.*.code' => [
|
||||
'required',
|
||||
@@ -77,6 +79,7 @@ class StoreTenantRequest extends FormRequest
|
||||
'search_items_per_page' => ['sometimes', 'integer', 'min:4', 'max:48'],
|
||||
'display_categories' => ['sometimes', 'boolean'],
|
||||
'display_seach_bar' => ['sometimes', 'boolean'],
|
||||
'display_cart' => ['sometimes', 'boolean'],
|
||||
'website_type_code' => [
|
||||
'required_with:extras',
|
||||
'sometimes',
|
||||
|
||||
@@ -73,6 +73,8 @@ class UpdateTenantRequest extends FormRequest
|
||||
'footer_bg_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'],
|
||||
'header_logo' => $logoRule,
|
||||
'footer_logo' => $logoRule,
|
||||
'header_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule],
|
||||
'footer_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule],
|
||||
'social_media' => ['sometimes', 'array'],
|
||||
'social_media.*.code' => [
|
||||
'required',
|
||||
@@ -87,6 +89,7 @@ class UpdateTenantRequest extends FormRequest
|
||||
'search_items_per_page' => ['sometimes', 'integer', 'min:4', 'max:48'],
|
||||
'display_categories' => ['sometimes', 'boolean'],
|
||||
'display_seach_bar' => ['sometimes', 'boolean'],
|
||||
'display_cart' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,11 +59,14 @@ class TenantResource extends JsonResource
|
||||
// 1 day
|
||||
'header_logo' => $this->headerLogo?->getTemporaryUrl(1440),
|
||||
'footer_logo' => $this->footerLogo?->getTemporaryUrl(1440),
|
||||
'header_bg_image' => $this->headerBackgroundImage?->getTemporaryUrl(1440),
|
||||
'footer_bg_image' => $this->footerBackgroundImage?->getTemporaryUrl(1440),
|
||||
'search_product_layout' => $this->search_product_layout->value,
|
||||
'search_group_layout' => $this->search_group_layout->value,
|
||||
'search_items_per_page' => $this->search_items_per_page,
|
||||
'display_categories' => $this->display_categories,
|
||||
'display_seach_bar' => $this->display_seach_bar,
|
||||
'display_cart' => $this->display_cart,
|
||||
'social_media' => $this->whenLoaded(
|
||||
'socialMedia',
|
||||
fn () => $this->socialMedia
|
||||
|
||||
@@ -13,6 +13,8 @@ class TenantInformationService
|
||||
private const DEFAULT_RELATIONS = [
|
||||
'headerLogo',
|
||||
'footerLogo',
|
||||
'headerBackgroundImage',
|
||||
'footerBackgroundImage',
|
||||
'socialMedia',
|
||||
'websiteExtras.websiteTypeExtra',
|
||||
'eventDates',
|
||||
|
||||
@@ -25,12 +25,16 @@ class TenantService
|
||||
return DB::transaction(function () use ($data): Tenant {
|
||||
$headerLogo = $data['header_logo'] ?? null;
|
||||
$footerLogo = $data['footer_logo'] ?? null;
|
||||
$headerBackgroundImage = $data['header_bg_image'] ?? null;
|
||||
$footerBackgroundImage = $data['footer_bg_image'] ?? null;
|
||||
$socialMedia = $data['social_media'] ?? [];
|
||||
$extras = $data['extras'] ?? [];
|
||||
|
||||
unset(
|
||||
$data['header_logo'],
|
||||
$data['footer_logo'],
|
||||
$data['header_bg_image'],
|
||||
$data['footer_bg_image'],
|
||||
$data['social_media'],
|
||||
$data['extras'],
|
||||
);
|
||||
@@ -59,6 +63,8 @@ class TenantService
|
||||
|
||||
$data['header_logo_id'] = $headerAttachmentId;
|
||||
$data['footer_logo_id'] = $footerAttachmentId;
|
||||
$data['header_bg_image_id'] = $this->storeTenantImage($headerBackgroundImage);
|
||||
$data['footer_bg_image_id'] = $this->storeTenantImage($footerBackgroundImage);
|
||||
|
||||
/** @var Tenant $tenant */
|
||||
$tenant = Tenant::query()->create($data);
|
||||
@@ -79,14 +85,20 @@ class TenantService
|
||||
return DB::transaction(function () use ($tenant, $data): Tenant {
|
||||
$hasHeaderLogoKey = array_key_exists('header_logo', $data);
|
||||
$hasFooterLogoKey = array_key_exists('footer_logo', $data);
|
||||
$hasHeaderBackgroundImageKey = array_key_exists('header_bg_image', $data);
|
||||
$hasFooterBackgroundImageKey = array_key_exists('footer_bg_image', $data);
|
||||
$hasSocialMediaKey = array_key_exists('social_media', $data);
|
||||
$headerLogo = $data['header_logo'] ?? null;
|
||||
$footerLogo = $data['footer_logo'] ?? null;
|
||||
$headerBackgroundImage = $data['header_bg_image'] ?? null;
|
||||
$footerBackgroundImage = $data['footer_bg_image'] ?? null;
|
||||
$socialMedia = $data['social_media'] ?? [];
|
||||
|
||||
unset(
|
||||
$data['header_logo'],
|
||||
$data['footer_logo'],
|
||||
$data['header_bg_image'],
|
||||
$data['footer_bg_image'],
|
||||
$data['social_media']
|
||||
);
|
||||
|
||||
@@ -124,6 +136,14 @@ class TenantService
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasHeaderBackgroundImageKey) {
|
||||
$tenant->header_bg_image_id = $this->storeTenantImage($headerBackgroundImage);
|
||||
}
|
||||
|
||||
if ($hasFooterBackgroundImageKey) {
|
||||
$tenant->footer_bg_image_id = $this->storeTenantImage($footerBackgroundImage);
|
||||
}
|
||||
|
||||
$tenant->save();
|
||||
|
||||
if ($hasSocialMediaKey) {
|
||||
@@ -151,4 +171,17 @@ class TenantService
|
||||
$tenant->socialMedia()->sync($associations);
|
||||
$tenant->unsetRelation('socialMedia');
|
||||
}
|
||||
|
||||
private function storeTenantImage(mixed $image): ?int
|
||||
{
|
||||
if (! $image) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attachment = is_string($image) && Str::isUuid($image)
|
||||
? Attachment::query()->where('key', $image)->first()
|
||||
: $this->attachmentService->store($image, 'tenants');
|
||||
|
||||
return $attachment?->id;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user