feat(website-type): add new color fields and update related methods in WebsiteType model and service
This commit is contained in:
@@ -17,6 +17,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
'secondary_color',
|
||||
'danger_color',
|
||||
'success_color',
|
||||
'warning_color',
|
||||
'body_color',
|
||||
'darker_body_color',
|
||||
'surface_color',
|
||||
'background_color',
|
||||
'border_color',
|
||||
'login_header_footer_color',
|
||||
'site_logo',
|
||||
])]
|
||||
|
||||
@@ -21,27 +21,58 @@ class WebsiteTypeService
|
||||
*/
|
||||
public function create(array $data): WebsiteType
|
||||
{
|
||||
return DB::transaction(function () use ($data): WebsiteType {
|
||||
return $this->save(new WebsiteType, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update a website type and replace its site logo when provided.
|
||||
*
|
||||
* @param array<string, mixed> $attributes
|
||||
* @param array<string, mixed> $values
|
||||
*/
|
||||
public function updateOrCreate(array $attributes, array $values = []): WebsiteType
|
||||
{
|
||||
/** @var WebsiteType $websiteType */
|
||||
$websiteType = WebsiteType::query()->firstOrNew($attributes);
|
||||
|
||||
return $this->save($websiteType, [...$attributes, ...$values]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
private function save(WebsiteType $websiteType, array $data): WebsiteType
|
||||
{
|
||||
return DB::transaction(function () use ($websiteType, $data): WebsiteType {
|
||||
$hasSiteLogo = array_key_exists('site_logo', $data);
|
||||
$siteLogo = $data['site_logo'] ?? null;
|
||||
$previousSiteLogo = $websiteType->exists
|
||||
? $websiteType->siteLogo()->first()
|
||||
: null;
|
||||
|
||||
unset($data['site_logo']);
|
||||
|
||||
$siteLogoAttachmentId = null;
|
||||
if ($hasSiteLogo) {
|
||||
$attachment = null;
|
||||
|
||||
if ($siteLogo) {
|
||||
$attachment = Str::isUuid($siteLogo)
|
||||
? Attachment::query()->where('key', $siteLogo)->first()
|
||||
: $this->attachmentService->store($siteLogo, 'website-types');
|
||||
|
||||
if ($attachment) {
|
||||
$siteLogoAttachmentId = $attachment->id;
|
||||
if ($siteLogo) {
|
||||
$attachment = is_string($siteLogo) && Str::isUuid($siteLogo)
|
||||
? Attachment::query()->where('key', $siteLogo)->first()
|
||||
: $this->attachmentService->store($siteLogo, 'website-types');
|
||||
}
|
||||
|
||||
$data['site_logo'] = $attachment?->id;
|
||||
}
|
||||
|
||||
$data['site_logo'] = $siteLogoAttachmentId;
|
||||
$websiteType->fill($data)->save();
|
||||
|
||||
/** @var WebsiteType $websiteType */
|
||||
$websiteType = WebsiteType::query()->create($data);
|
||||
if (
|
||||
$hasSiteLogo
|
||||
&& $previousSiteLogo instanceof Attachment
|
||||
&& $previousSiteLogo->id !== $websiteType->site_logo
|
||||
) {
|
||||
$this->attachmentService->delete($previousSiteLogo);
|
||||
}
|
||||
|
||||
return $websiteType;
|
||||
});
|
||||
|
||||
@@ -14,7 +14,13 @@ return new class extends Migration
|
||||
$table->string('secondary_color')->nullable()->after('primary_color');
|
||||
$table->string('danger_color')->nullable()->after('secondary_color');
|
||||
$table->string('success_color')->nullable()->after('danger_color');
|
||||
$table->string('login_header_footer_color')->nullable()->after('success_color');
|
||||
$table->string('warning_color')->nullable()->after('success_color');
|
||||
$table->string('body_color')->nullable()->after('warning_color');
|
||||
$table->string('darker_body_color')->nullable()->after('body_color');
|
||||
$table->string('surface_color')->nullable()->after('darker_body_color');
|
||||
$table->string('background_color')->nullable()->after('surface_color');
|
||||
$table->string('border_color')->nullable()->after('background_color');
|
||||
$table->string('login_header_footer_color')->nullable()->after('border_color');
|
||||
$table->unsignedBigInteger('site_logo')->nullable()->after('login_header_footer_color');
|
||||
|
||||
$table->foreign('site_logo')
|
||||
@@ -37,6 +43,12 @@ return new class extends Migration
|
||||
'secondary_color',
|
||||
'danger_color',
|
||||
'success_color',
|
||||
'warning_color',
|
||||
'body_color',
|
||||
'darker_body_color',
|
||||
'surface_color',
|
||||
'background_color',
|
||||
'border_color',
|
||||
'login_header_footer_color',
|
||||
'site_logo',
|
||||
]);
|
||||
|
||||
@@ -2,16 +2,37 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Domains\Tenant\Models\WebsiteType;
|
||||
use App\Domains\Tenant\Services\WebsiteTypeService;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use RuntimeException;
|
||||
|
||||
class WebsiteTypeSeeder extends Seeder
|
||||
{
|
||||
private const PRESENTATION = [
|
||||
'primary_color' => '#FF7006',
|
||||
'secondary_color' => '#777777',
|
||||
'danger_color' => '#E04A4A',
|
||||
'success_color' => '#81BC73',
|
||||
'warning_color' => '#81BC73',
|
||||
'body_color' => '#666666',
|
||||
'darker_body_color' => '#333333',
|
||||
'surface_color' => '#ffffff',
|
||||
'background_color' => '#f8f8f8',
|
||||
'border_color' => '#f8f8f8',
|
||||
];
|
||||
|
||||
public function __construct(private readonly WebsiteTypeService $websiteTypeService) {}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$shopIt = WebsiteType::query()->updateOrCreate(
|
||||
$shopIt = $this->websiteTypeService->updateOrCreate(
|
||||
['codigo' => 'shopit'],
|
||||
['nombre' => 'ShopIt'],
|
||||
[
|
||||
'nombre' => 'ShopIt',
|
||||
...self::PRESENTATION,
|
||||
'site_logo' => $this->onTicketLogo(),
|
||||
],
|
||||
);
|
||||
|
||||
$shopIt->extras()->updateOrCreate(
|
||||
@@ -35,9 +56,13 @@ class WebsiteTypeSeeder extends Seeder
|
||||
],
|
||||
);
|
||||
|
||||
$onTicket = WebsiteType::query()->updateOrCreate(
|
||||
$onTicket = $this->websiteTypeService->updateOrCreate(
|
||||
['codigo' => 'onticket'],
|
||||
['nombre' => 'OnTicket'],
|
||||
[
|
||||
'nombre' => 'OnTicket',
|
||||
...self::PRESENTATION,
|
||||
'site_logo' => $this->onTicketLogo(),
|
||||
],
|
||||
);
|
||||
|
||||
$onTicket->extras()->updateOrCreate(
|
||||
@@ -85,4 +110,21 @@ class WebsiteTypeSeeder extends Seeder
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
private function onTicketLogo(): UploadedFile
|
||||
{
|
||||
$path = public_path('images/website_types/shopit_logo.png');
|
||||
|
||||
if (! file_exists($path)) {
|
||||
throw new RuntimeException("OnTicket logo not found at path: {$path}");
|
||||
}
|
||||
|
||||
return new UploadedFile(
|
||||
$path,
|
||||
'onticket_logo.png',
|
||||
'image/png',
|
||||
null,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace Tests\Feature\Seeders;
|
||||
|
||||
use App\Domains\Attachable\Models\Attachment;
|
||||
use App\Domains\Tenant\Models\WebsiteType;
|
||||
use Database\Seeders\WebsiteTypeSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\TestCase;
|
||||
|
||||
class WebsiteTypeSeederTest extends TestCase
|
||||
@@ -13,10 +15,26 @@ class WebsiteTypeSeederTest extends TestCase
|
||||
|
||||
public function test_it_seeds_website_types_and_their_config_schemas_idempotently(): void
|
||||
{
|
||||
Storage::fake('s3');
|
||||
|
||||
$this->seed(WebsiteTypeSeeder::class);
|
||||
$this->seed(WebsiteTypeSeeder::class);
|
||||
|
||||
$this->assertSame(2, WebsiteType::query()->count());
|
||||
$this->assertSame(2, Attachment::query()->count());
|
||||
|
||||
$expectedPresentation = [
|
||||
'primary_color' => '#FF7006',
|
||||
'secondary_color' => '#777777',
|
||||
'danger_color' => '#E04A4A',
|
||||
'success_color' => '#81BC73',
|
||||
'warning_color' => '#81BC73',
|
||||
'body_color' => '#666666',
|
||||
'darker_body_color' => '#333333',
|
||||
'surface_color' => '#ffffff',
|
||||
'background_color' => '#f8f8f8',
|
||||
'border_color' => '#f8f8f8',
|
||||
];
|
||||
|
||||
$shopIt = WebsiteType::query()
|
||||
->where('codigo', 'shopit')
|
||||
@@ -24,6 +42,9 @@ class WebsiteTypeSeederTest extends TestCase
|
||||
->sole();
|
||||
|
||||
$this->assertSame('ShopIt', $shopIt->nombre);
|
||||
$this->assertSame($expectedPresentation, $shopIt->only(array_keys($expectedPresentation)));
|
||||
$this->assertSame('onticket_logo.png', $shopIt->siteLogo->filename);
|
||||
Storage::disk('s3')->assertExists($shopIt->siteLogo->path);
|
||||
$this->assertSame(['carousel'], $shopIt->extras->pluck('codigo')->all());
|
||||
$this->assertSame('Carrusel principal', $shopIt->extras->sole()->nombre);
|
||||
$this->assertSame([
|
||||
@@ -45,6 +66,10 @@ class WebsiteTypeSeederTest extends TestCase
|
||||
->sole();
|
||||
|
||||
$this->assertSame('OnTicket', $onTicket->nombre);
|
||||
$this->assertSame($expectedPresentation, $onTicket->only(array_keys($expectedPresentation)));
|
||||
$this->assertSame('onticket_logo.png', $onTicket->siteLogo->filename);
|
||||
Storage::disk('s3')->assertExists($onTicket->siteLogo->path);
|
||||
$this->assertNotSame($shopIt->site_logo, $onTicket->site_logo);
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['heroConfig', 'eventConfig'],
|
||||
$onTicket->extras->pluck('codigo')->all(),
|
||||
|
||||
@@ -27,6 +27,12 @@ class WebsiteExtrasTest extends TestCase
|
||||
'secondary_color',
|
||||
'danger_color',
|
||||
'success_color',
|
||||
'warning_color',
|
||||
'body_color',
|
||||
'darker_body_color',
|
||||
'surface_color',
|
||||
'background_color',
|
||||
'border_color',
|
||||
'login_header_footer_color',
|
||||
'site_logo',
|
||||
'created_at',
|
||||
@@ -73,6 +79,12 @@ class WebsiteExtrasTest extends TestCase
|
||||
'secondary_color' => '#222222',
|
||||
'danger_color' => '#ff0000',
|
||||
'success_color' => '#00aa55',
|
||||
'warning_color' => '#ffaa00',
|
||||
'body_color' => '#666666',
|
||||
'darker_body_color' => '#333333',
|
||||
'surface_color' => '#ffffff',
|
||||
'background_color' => '#f8f8f8',
|
||||
'border_color' => '#dddddd',
|
||||
'login_header_footer_color' => '#333333',
|
||||
'site_logo' => $siteLogo->id,
|
||||
]);
|
||||
@@ -100,6 +112,12 @@ class WebsiteExtrasTest extends TestCase
|
||||
$this->assertSame('#222222', $type->secondary_color);
|
||||
$this->assertSame('#ff0000', $type->danger_color);
|
||||
$this->assertSame('#00aa55', $type->success_color);
|
||||
$this->assertSame('#ffaa00', $type->warning_color);
|
||||
$this->assertSame('#666666', $type->body_color);
|
||||
$this->assertSame('#333333', $type->darker_body_color);
|
||||
$this->assertSame('#ffffff', $type->surface_color);
|
||||
$this->assertSame('#f8f8f8', $type->background_color);
|
||||
$this->assertSame('#dddddd', $type->border_color);
|
||||
$this->assertSame('#333333', $type->login_header_footer_color);
|
||||
$this->assertTrue($type->siteLogo()->firstOrFail()->is($siteLogo));
|
||||
$this->assertSame($type->codigo, $typeExtra->website_type_code);
|
||||
|
||||
@@ -24,6 +24,12 @@ class WebsiteTypeServiceTest extends TestCase
|
||||
'secondary_color' => '#222222',
|
||||
'danger_color' => '#ff0000',
|
||||
'success_color' => '#00aa55',
|
||||
'warning_color' => '#ffaa00',
|
||||
'body_color' => '#666666',
|
||||
'darker_body_color' => '#333333',
|
||||
'surface_color' => '#ffffff',
|
||||
'background_color' => '#f8f8f8',
|
||||
'border_color' => '#dddddd',
|
||||
'login_header_footer_color' => '#333333',
|
||||
'site_logo' => UploadedFile::fake()->image('site-logo.png'),
|
||||
]);
|
||||
@@ -37,6 +43,12 @@ class WebsiteTypeServiceTest extends TestCase
|
||||
$this->assertDatabaseHas('website_type', [
|
||||
'codigo' => 'marketplace',
|
||||
'dominio' => 'marketplace.test',
|
||||
'warning_color' => '#ffaa00',
|
||||
'body_color' => '#666666',
|
||||
'darker_body_color' => '#333333',
|
||||
'surface_color' => '#ffffff',
|
||||
'background_color' => '#f8f8f8',
|
||||
'border_color' => '#dddddd',
|
||||
'login_header_footer_color' => '#333333',
|
||||
'site_logo' => $siteLogo->id,
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user