Skip to content

Commit

Permalink
Merge pull request laravel#14 from Artisans-PXM/templates
Browse files Browse the repository at this point in the history
Templates
  • Loading branch information
utsavsomaiya authored Jul 12, 2023
2 parents df98494 + 7ea0fb8 commit d67b20b
Show file tree
Hide file tree
Showing 14 changed files with 441 additions and 39 deletions.
3 changes: 2 additions & 1 deletion app/Enums/PermissionEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum PermissionEnum: int
case CURRENCIES = 3;
case HIERARCHIES = 4;
case PRICE_BOOKS = 5;
case TEMPLATES = 6;

public static function getFeatureGates(): Collection
{
Expand Down Expand Up @@ -52,7 +53,7 @@ private static function generateAction(string $action, string $for): string

// Ref: if action is create, update or delete then the return value is `create-locale`, `delete-locale` or `update-locale`
return Str::of($action)
->append('-', Str::of($for)->title()->value())
->append('-', Str::title($for))
->slug()
->value();
}
Expand Down
59 changes: 59 additions & 0 deletions app/Http/Controllers/Api/TemplateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\TemplateRequest;
use App\Http\Resources\Api\TemplateResource;
use App\Queries\TemplateQueries;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class TemplateController extends Controller
{
public function __construct(
protected TemplateQueries $templateQueries
) {

}

public function fetch(): AnonymousResourceCollection
{
$templates = $this->templateQueries->listQuery();

return TemplateResource::collection($templates->getCollection());
}

public function create(TemplateRequest $request): JsonResponse
{
$validatedData = $request->validated();

$this->templateQueries->create($validatedData);

return response()->json([
'success' => __('Template created successfully.'),
]);
}

public function delete(string $id): JsonResponse
{
$this->templateQueries->delete($id);

return response()->json([
'success' => __('Template deleted successfully.'),
]);
}

public function update(TemplateRequest $request, string $id): JsonResponse
{
$validatedData = $request->validated();

$this->templateQueries->update($validatedData, $id);

return response()->json([
'success' => __('Template updated successfully.'),
]);
}
}
37 changes: 37 additions & 0 deletions app/Http/Requests/Api/TemplateRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests\Api;

use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Str;

class TemplateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, (ValidationRule | array<int, string> | string)>
*/
public function rules(): array
{
return [
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'slug' => ['sometimes'],
];
}

/**
* @param array<int, string>|int|string|null $key
* @return array<string, mixed>
*/
public function validated($key = null, $default = null): array
{
return array_merge(parent::validated(), [
'slug' => Str::slug($this->slug),
]);
}
}
27 changes: 27 additions & 0 deletions app/Http/Resources/Api/TemplateResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace App\Http\Resources\Api;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class TemplateResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
$template = $this->resource;

return [
'id' => $template->id,
'name' => $template->name,
'description' => $template->description,
];
}
}
42 changes: 42 additions & 0 deletions app/Models/Template.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;

class Template extends Model
{
use HasFactory;
use HasUuids;
use HasSlug;

/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['company_id', 'name', 'description', 'slug'];

/**
* Get the options for generating the slug.
*/
public function getSlugOptions(): SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('name')
->saveSlugsTo('slug')
->preventOverwrite();
}

public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
}
52 changes: 52 additions & 0 deletions app/Queries/TemplateQueries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace App\Queries;

use App\Models\Template;
use Illuminate\Pagination\LengthAwarePaginator;
use Spatie\QueryBuilder\QueryBuilder;

class TemplateQueries
{
public function listQuery(): LengthAwarePaginator
{
return QueryBuilder::for(Template::class)
->allowedFields(['id', 'name', 'description'])
->defaultSort('-id')
->allowedSorts(['id', 'name'])
->jsonPaginate();
}

/**
* @param array<string, string> $data
*/
public function create(array $data): void
{
$data['company_id'] ??= app('company_id');

Template::create($data);
}

public function delete(string $id): void
{
Template::query()
->where('company_id', app('company_id'))
->where('id', $id)
->delete();
}

/**
* @param array<string, string> $data
*/
public function update(array $data, string $id): void
{
$data['company_id'] ??= app('company_id');

Template::query()
->where('company_id', app('company_id'))
->where('id', $id)
->update($data);
}
}
31 changes: 31 additions & 0 deletions database/factories/TemplateFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\Template;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use App\Models\Company;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
* @extends Factory<Template>
*/
class TemplateFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'company_id' => fn (): Collection|Model => Company::factory()->create(),
'name' => fake()->word(),
'description' => fake()->sentence(),
];
}
}
33 changes: 33 additions & 0 deletions database/migrations/2023_07_12_094121_create_templates_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

use App\Models\Company;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('templates', function (Blueprint $table): void {
$table->uuid('id')->primary();
$table->foreignIdFor(Company::class, 'company_id')->constrained('companies');
$table->string('name');
$table->longText('description')->nullable();
$table->string('slug');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('templates');
}
};
64 changes: 28 additions & 36 deletions database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

use App\Models\Company;
use App\Models\User;
use Illuminate\Console\Command;
use Database\Factories\CompanyFactory;
use Illuminate\Console\View\Components\Factory;
use Illuminate\Console\View\Components\TwoColumnDetail;

class DatabaseSeeder extends GenerateCsvDataSeeder
{
Expand All @@ -18,53 +19,44 @@ public function run(): void
{
$time = microtime(true);

$this->command->warn('Creating companies...');
Company::factory(2)->create();
$this->command->info('Companies created.');
$this->fakerCompanySeeding();

$companyMinimumId = Company::min('id');

$this->command->warn(PHP_EOL.'Creating users...');

$success = $this->seedDataFromCsvFile(database_path('/seeders/csv/users.csv'));
if ($success === Command::SUCCESS) {
$this->command->info('Users created.');
}
$this->seedDataFromCsvFile(database_path('/seeders/csv/users.csv'));

$this->command->warn(PHP_EOL.'Creating roles');
$success = $this->seedDataFromCsvFile(database_path('/seeders/csv/roles.csv'));
if ($success === Command::SUCCESS) {
$this->command->info('Roles created.');
}
$this->seedDataFromCsvFile(database_path('/seeders/csv/roles.csv'));

User::cursor()->each(function (User $user): void {
$user->assignRole(['Super Admin']);
$user->companies()->attach(Company::min('id'), ['created_at' => now(), 'updated_at' => now()]);
});

$this->command->warn(PHP_EOL.'Creating Locales...');
$success = $this->seedDataFromCsvFile(database_path('/seeders/csv/locales.csv'), companyId: $companyMinimumId);
if ($success === Command::SUCCESS) {
$this->command->info('Locales created.');
}

$this->command->warn(PHP_EOL.'Creating Currencies...');
$success = $this->seedDataFromCsvFile(database_path('/seeders/csv/currencies.csv'), companyId: $companyMinimumId);
if ($success === Command::SUCCESS) {
$this->command->info('Currencies created.');
}

$this->command->warn(PHP_EOL.'Creating Price books...');
$success = $this->seedDataFromCsvFile(database_path('/seeders/csv/price_books.csv'), companyId: $companyMinimumId);
if ($success === Command::SUCCESS) {
$this->command->info('Currencies created.');
}

$this->command->newLine();
$this->seedDataFromCsvFile(database_path('/seeders/csv/locales.csv'), companyId: $companyMinimumId);

$this->seedDataFromCsvFile(database_path('/seeders/csv/currencies.csv'), companyId: $companyMinimumId);

$this->seedDataFromCsvFile(database_path('/seeders/csv/price_books.csv'), companyId: $companyMinimumId);

$this->call(HierarchySeeder::class, parameters: ['companyId' => $companyMinimumId]);

$secs = microtime(true) - $time;
$this->seedDataFromCsvFile(database_path('/seeders/csv/templates.csv'), companyId: $companyMinimumId);

app()->make(Factory::class, ['output' => $this->command->getOutput()])
->info('All this took '.round($secs * 1000).'ms');
->info('All this took '.number_format((microtime(true) - $time) * 1000, 2).' ms');
}

private function fakerCompanySeeding(): void
{
with(new TwoColumnDetail($this->command->getOutput()))->render(CompanyFactory::class, '<fg=yellow;options=bold>RUNNING</>');

$startTime = microtime(true);

Company::factory(2)->create();

$runTime = number_format((microtime(true) - $startTime) * 1000, 2);

with(new TwoColumnDetail($this->command->getOutput()))->render(CompanyFactory::class, sprintf('<fg=gray>%s ms</> <fg=green;options=bold>DONE</>', $runTime));
$this->command->getOutput()->writeln('');
}
}
Loading

0 comments on commit d67b20b

Please sign in to comment.