Browse Source

requirement create

moell 1 year ago
parent
commit
6b5098c723

+ 1 - 1
app/Http/Controllers/API/AssetController.php

@@ -33,7 +33,7 @@ class AssetController extends Controller
             'created_by' => Auth::id(),
         ]);
 
-        return $this->noContent();
+        return $this->created();
     }
 
     /**

+ 65 - 0
app/Http/Controllers/API/RequirementController.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Http\Controllers\API;
+
+use App\Http\Controllers\Controller;
+use App\Http\Requests\API\Requirement\CreateOrUpdateRequest;
+use App\Models\Requirement;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+
+class RequirementController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     */
+    public function store(CreateOrUpdateRequest $request)
+    {
+        $requirement = new Requirement();
+
+        $requirement->mergeFillable([
+            'company_id', 'created_by',
+        ]);
+
+        $requirement->fill([
+            ...$request->all(),
+            'company_id' => Auth::user()->company_id,
+            'created_by' => Auth::id(),
+        ]);
+        $requirement->save();
+
+        return $this->created();
+    }
+
+    /**
+     * Display the specified resource.
+     */
+    public function show(string $id)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     */
+    public function update(Request $request, string $id)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     */
+    public function destroy(string $id)
+    {
+        //
+    }
+}

+ 58 - 0
app/Http/Requests/API/Requirement/CreateOrUpdateRequest.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Http\Requests\API\Requirement;
+
+use App\Http\Requests\RuleHelper;
+use App\Models\Enums\RequirementStatus;
+use App\Models\User;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Validation\Rule;
+use Illuminate\Validation\Rules\Enum;
+
+class CreateOrUpdateRequest extends FormRequest
+{
+    use RuleHelper;
+
+    /**
+     * Determine if the user is authorized to make this request.
+     */
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
+     */
+    public function rules(): array
+    {
+        return [
+            'title' => 'required|max:255',
+            'status' => [
+                'required',
+                new Enum(RequirementStatus::class),
+            ],
+            'asset_id' => [
+                'required',
+                Rule::exists('assets', 'id')->where($this->userCompanyWhere()),
+            ],
+            'mailto' => [
+                'array',
+                function ($attribute, $value, $fail) {
+                    $userCount = User::where("company_id", Auth::user()->company_id)->whereIn('id', $value)->count();
+                    if ($userCount != count($value)) {
+                        $fail('The selected user is invalid.');
+                    }
+                }
+            ],
+            'priority' => 'required|in:1,2,3,4',
+            'requirement_group_id' => [
+                'required',
+                Rule::exists('requirement_groups', 'id')->where($this->userCompanyWhere()),
+            ]
+        ];
+    }
+}

+ 16 - 0
app/ModelFilters/RequirementFilter.php

@@ -0,0 +1,16 @@
+<?php 
+
+namespace App\ModelFilters;
+
+use EloquentFilter\ModelFilter;
+
+class RequirementFilter extends ModelFilter
+{
+    /**
+    * Related Models that have ModelFilters as well as the method on the ModelFilter
+    * As [relationMethod => [input_key1, input_key2]].
+    *
+    * @var array
+    */
+    public $relations = [];
+}

+ 14 - 0
app/Models/Enums/RequirementStatus.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Models\Enums;
+
+enum RequirementStatus: string
+{
+    case CHANGED = 'changed';
+
+    case ACTIVE = 'active';
+
+    case DRAFT = 'draft';
+
+    case CLOSED = 'closed';
+}

+ 28 - 0
app/Models/Requirement.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class Requirement extends Model
+{
+    use HasFactory;
+
+    protected $fillable = [
+        'title',
+        'asset_id',
+        'status',
+        'requirement_group_id',
+        'priority',
+        'note',
+        'description',
+        'acceptance',
+        'mailto',
+        'company_id',
+    ];
+
+    protected $casts = [
+        'mailto' => 'array',
+    ];
+}

+ 1 - 0
app/Models/User.php

@@ -22,6 +22,7 @@ class User extends Authenticatable
         'username',
         'email',
         'password',
+        'company_id',
     ];
 
     /**

+ 38 - 0
database/factories/RequirementFactory.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace Database\Factories;
+
+use App\Models\Asset;
+use App\Models\Enums\RequirementStatus;
+use App\Models\RequirementGroup;
+use App\Models\User;
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+/**
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Requirement>
+ */
+class RequirementFactory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array<string, mixed>
+     */
+    public function definition(): array
+    {
+        return [
+            'title' => fake()->title(),
+            'asset_id' => Asset::factory()->create()->id,
+            'status' => RequirementStatus::CHANGED->value,
+            'requirement_group_id' => RequirementGroup::factory()->create()->id,
+            'priority' => rand(1, 4),
+            'note' => fake()->text(30),
+            'description' => fake()->text(),
+            'acceptance' => fake()->text(),
+            'mailto' => [
+                User::factory()->create()->id,
+                User::factory()->create()->id
+            ],
+        ];
+    }
+}

+ 2 - 0
database/factories/UserFactory.php

@@ -29,6 +29,8 @@ class UserFactory extends Factory
             'email_verified_at' => now(),
             'password' => static::$password ??= Hash::make('password'),
             'remember_token' => Str::random(10),
+            'username' => fake()->unique()->userName(),
+            'company_id' => 1,
         ];
     }
 

+ 40 - 0
database/migrations/2024_01_20_083910_create_requirement_table.php

@@ -0,0 +1,40 @@
+<?php
+
+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('requirements', function (Blueprint $table) {
+            $table->id();
+            $table->string('title');
+            $table->enum('status', ['changed', 'active', 'draft', 'closed'])->default('draft');
+            $table->integer('asset_id');
+            $table->integer('company_id');
+            $table->integer('requirement_group_id');
+            $table->integer('reviewed_by')->nullable();
+            $table->tinyInteger('priority')->default(1);
+            $table->string('note')->nullable();
+            $table->text('description')->nullable();
+            $table->text('acceptance')->nullable();
+            $table->json('mailto');
+            $table->integer('created_by');
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('requirements');
+    }
+};

+ 1 - 0
routes/api.php

@@ -29,5 +29,6 @@ Route::middleware(['auth:sanctum'])->group(function () {
         'asset-group' => API\AssetGroupController::class,
         'asset' => API\AssetController::class,
         'requirement-group' => API\RequirementGroupController::class,
+        'requirement' => API\RequirementController::class,
     ]);
 });

+ 1 - 1
tests/Feature/API/AssetTest.php

@@ -44,7 +44,7 @@ class AssetTest extends TestCase
 
         $response = $this->post(route('asset.store'), $form->toArray());
 
-        $response->assertStatus(204);
+        $response->assertStatus(201);
     }
 
     public function test_asset_group_update(): void

+ 20 - 0
tests/Feature/API/RequirementTest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Tests\Feature\API;
+
+use App\Models\Requirement;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Foundation\Testing\WithFaker;
+use Tests\Feature\TestCase;
+
+class RequirementTest extends TestCase
+{
+    public function test_requirement_create(): void
+    {
+        $form = Requirement::factory()->make();
+
+        $response = $this->post(route('requirement.store'), $form->toArray());
+
+        $response->assertStatus(201);
+    }
+}