diff --git a/app/FamilyConnection.php b/app/FamilyConnection.php new file mode 100644 index 0000000..6763c19 --- /dev/null +++ b/app/FamilyConnection.php @@ -0,0 +1,19 @@ +get('set_father_id')) { $user->father_id = $request->get('set_father_id'); $user->save(); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $request->get('set_father_id'), + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } else { $father = new User; $father->id = Uuid::uuid4()->toString(); @@ -35,6 +44,13 @@ class FamilyActionsController extends Controller $father->manager_id = auth()->id(); $user->setFather($father); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $father->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } return back(); @@ -57,6 +73,13 @@ class FamilyActionsController extends Controller if ($request->get('set_mother_id')) { $user->mother_id = $request->get('set_mother_id'); $user->save(); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $request->get('set_mother_id'), + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } else { $mother = new User; $mother->id = Uuid::uuid4()->toString(); @@ -66,6 +89,13 @@ class FamilyActionsController extends Controller $mother->manager_id = auth()->id(); $user->setMother($mother); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $mother->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } return back(); @@ -107,8 +137,22 @@ class FamilyActionsController extends Controller } else { if ($user->gender_id == 1) { $child->setFather($user); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $child->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } else { $child->setMother($user); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $child->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } } @@ -146,6 +190,13 @@ class FamilyActionsController extends Controller $user->addWife($wife, $request->get('marriage_date')); + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $wife->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); + return back(); } @@ -177,6 +228,13 @@ class FamilyActionsController extends Controller $user->addHusband($husband, $request->get('marriage_date')); + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $husband->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); + return back(); } diff --git a/app/Http/Controllers/Users/FamilyConnectionRequestController.php b/app/Http/Controllers/Users/FamilyConnectionRequestController.php new file mode 100644 index 0000000..3a07dd2 --- /dev/null +++ b/app/Http/Controllers/Users/FamilyConnectionRequestController.php @@ -0,0 +1,55 @@ + Uuid::uuid4()->toString(), + 'requester_id' => auth()->id(), + 'requested_id' => $user->id, + 'status_id' => FamilyConnection::STATUS_WAITING, + ]); + + return back(); + } + + public function update(Request $request, User $user) + { + $familyConnection = FamilyConnection::where([ + 'requester_id' => $user->id, + 'requested_id' => auth()->id(), + 'status_id' => FamilyConnection::STATUS_WAITING, + ])->first(); + + $familyConnection->status_id = FamilyConnection::STATUS_APPROVED; + $familyConnection->save(); + + return back(); + } + + public function destroy(Request $request, User $user) + { + $familyConnection = FamilyConnection::where([ + 'requester_id' => $user->id, + 'requested_id' => auth()->id(), + 'status_id' => FamilyConnection::STATUS_WAITING, + ])->orWhere([ + 'requester_id' => auth()->id(), + 'requested_id' => $user->id, + 'status_id' => FamilyConnection::STATUS_WAITING, + ])->first(); + + $familyConnection->delete(); + + return back(); + } +} diff --git a/app/User.php b/app/User.php index 26bafb6..ec6b1de 100644 --- a/app/User.php +++ b/app/User.php @@ -147,6 +147,7 @@ class User extends Authenticatable 'marriage_date' => $marriageDate, 'manager_id' => auth()->id(), ]); + return $wife; } @@ -166,6 +167,7 @@ class User extends Authenticatable 'marriage_date' => $marriageDate, 'manager_id' => auth()->id(), ]); + return $husband; } @@ -314,4 +316,26 @@ class User extends Authenticatable return Carbon::now()->diffInDays($this->birthday, false); } } + + public function hasFamilyConnectionRequestTo(User $user) + { + $familyConnetction = FamilyConnection::where([ + 'requester_id' => $this->id, + 'requested_id' => $user->id, + 'status_id' => 0, + ])->count(); + + return !!$familyConnetction; + } + + public function hasPendingFamilyConnectionRequestFrom(User $user) + { + $familyConnetction = FamilyConnection::where([ + 'requester_id' => $user->id, + 'requested_id' => $this->id, + 'status_id' => 0, + ])->count(); + + return !!$familyConnetction; + } } diff --git a/database/migrations/2021_03_28_091809_create_family_connections_table.php b/database/migrations/2021_03_28_091809_create_family_connections_table.php new file mode 100644 index 0000000..ff26a90 --- /dev/null +++ b/database/migrations/2021_03_28_091809_create_family_connections_table.php @@ -0,0 +1,36 @@ +uuid('id')->primary(); + $table->uuid('requester_id'); + $table->uuid('requested_id'); + $table->unsignedTinyInteger('status_id')->default(0); + $table->timestamps(); + + $table->unique(['requester_id', 'requested_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('family_member_connections'); + } +} diff --git a/resources/views/users/partials/action-buttons.blade.php b/resources/views/users/partials/action-buttons.blade.php index 4b78ac1..7ab4d64 100644 --- a/resources/views/users/partials/action-buttons.blade.php +++ b/resources/views/users/partials/action-buttons.blade.php @@ -6,4 +6,16 @@ {{ link_to_route('users.chart', trans('app.show_family_chart'), [$user->id], ['class' => Request::segment(3) == 'chart' ? 'btn btn-default active' : 'btn btn-default']) }} {{ link_to_route('users.tree', trans('app.show_family_tree'), [$user->id], ['class' => Request::segment(3) == 'tree' ? 'btn btn-default active' : 'btn btn-default']) }} {{ link_to_route('users.marriages', trans('app.show_marriages'), [$user->id], ['class' => Request::segment(3) == 'marriages' ? 'btn btn-default active' : 'btn btn-default']) }} - \ No newline at end of file + @auth + @if (auth()->user()->hasFamilyConnectionRequestTo($user)) + {!! FormField::delete(['route' => ['users.family_connection_requests.destroy', $user->id]], __('family_connection.cancel_request'), ['class' => 'btn btn-warning', 'id' => 'cancel_family_connection_request']) !!} + @else + {!! FormField::formButton(['route' => ['users.family_connection_requests.store', $user->id]], __('family_connection.send_request'), ['class' => 'btn btn-success', 'id' => 'send_family_connection_request']) !!} + @endif + + @if (auth()->user()->hasPendingFamilyConnectionRequestFrom($user)) + {!! FormField::formButton(['route' => ['users.family_connection_requests.update', $user->id], 'method' => 'patch'], __('family_connection.accept_request'), ['class' => 'btn btn-success', 'id' => 'accept_family_connection_request']) !!} + {!! FormField::delete(['route' => ['users.family_connection_requests.destroy', $user->id]], __('family_connection.reject_request'), ['class' => 'btn btn-danger', 'id' => 'reject_family_connection_request']) !!} + @endif + @endauth + diff --git a/routes/web.php b/routes/web.php index 7403c45..5e985c2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -18,6 +18,15 @@ Auth::routes(); Route::group(['middleware' => 'auth'], function () { Route::get('password/change', 'Auth\ChangePasswordController@show')->name('password.change'); Route::post('password/change', 'Auth\ChangePasswordController@update')->name('password.change'); + + Route::post('users/{user}/send_family_connection_request', 'Users\FamilyConnectionRequestController@store') + ->name('users.family_connection_requests.store'); + + Route::patch('users/{user}/accept_family_connection_request', 'Users\FamilyConnectionRequestController@update') + ->name('users.family_connection_requests.update'); + + Route::delete('users/{user}/cancel_family_connection_request', 'Users\FamilyConnectionRequestController@destroy') + ->name('users.family_connection_requests.destroy'); }); Route::get('home', 'HomeController@index')->name('home'); diff --git a/tests/Feature/FamilyConnectionRequestTest.php b/tests/Feature/FamilyConnectionRequestTest.php new file mode 100644 index 0000000..81e20f0 --- /dev/null +++ b/tests/Feature/FamilyConnectionRequestTest.php @@ -0,0 +1,110 @@ +loginAsUser(); + $otherPerson = factory(User::class)->create(); + + $this->dontSeeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $otherPerson->id, + ]); + + $this->visitRoute('users.show', $otherPerson); + $this->seeElement('button', ['id' => 'send_family_connection_request']); + $this->press('send_family_connection_request'); + $this->seeRouteIs('users.show', $otherPerson); + $this->seeElement('button', ['id' => 'cancel_family_connection_request']); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $otherPerson->id, + ]); + } + + /** @test */ + public function user_can_cancel_family_connection_request_to_other_user() + { + $user = $this->loginAsUser(); + $otherPerson = factory(User::class)->create(); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $user->id, + 'requested_id' => $otherPerson->id, + ]); + + $this->visitRoute('users.show', $otherPerson); + $this->seeElement('button', ['id' => 'cancel_family_connection_request']); + $this->press('cancel_family_connection_request'); + + $this->dontSeeInDatabase('family_connections', [ + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + ]); + } + + /** @test */ + public function user_can_accept_family_connection_request_from_other_user() + { + $user = $this->loginAsUser(); + $otherPerson = factory(User::class)->create(); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + ]); + + $this->visitRoute('users.show', $otherPerson); + $this->seeElement('button', ['id' => 'accept_family_connection_request']); + $this->press('accept_family_connection_request'); + + $this->seeRouteIs('users.show', $otherPerson); + $this->seeInDatabase('family_connections', [ + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); + } + + /** @test */ + public function user_can_reject_family_connection_request_from_other_user() + { + $user = $this->loginAsUser(); + $otherPerson = factory(User::class)->create(); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + ]); + $this->seeInDatabase('family_connections', [ + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + ]); + + $this->visitRoute('users.show', $otherPerson); + $this->seeElement('button', ['id' => 'reject_family_connection_request']); + $this->press('reject_family_connection_request'); + + $this->seeRouteIs('users.show', $otherPerson); + $this->dontSeeInDatabase('family_connections', [ + 'requester_id' => $otherPerson->id, + 'requested_id' => $user->id, + ]); + } +} diff --git a/tests/Feature/ManageUserFamiliesTest.php b/tests/Feature/ManageUserFamiliesTest.php index 47f1f3f..c038c69 100644 --- a/tests/Feature/ManageUserFamiliesTest.php +++ b/tests/Feature/ManageUserFamiliesTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature; +use App\FamilyConnection; use App\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; @@ -30,6 +31,12 @@ class ManageUserFamiliesTest extends TestCase ]); $this->assertEquals('Nama Ayah', $user->fresh()->father->nickname); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $user->fresh()->father->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -53,6 +60,12 @@ class ManageUserFamiliesTest extends TestCase ]); $this->assertEquals('Nama Ibu', $user->fresh()->mother->nickname); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $user->fresh()->mother->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -80,6 +93,13 @@ class ManageUserFamiliesTest extends TestCase 'parent_id' => null, 'manager_id' => $user->id, ]); + $child = User::where('name', 'Nama Anak 1')->first(); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $child->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -170,6 +190,12 @@ class ManageUserFamiliesTest extends TestCase 'marriage_date' => '2010-01-01', 'manager_id' => $user->id, ]); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $wife->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -203,6 +229,12 @@ class ManageUserFamiliesTest extends TestCase 'marriage_date' => '2010-03-03', 'manager_id' => $user->id, ]); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $husband->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -225,6 +257,12 @@ class ManageUserFamiliesTest extends TestCase ]); $this->assertEquals($father->nickname, $user->fresh()->father->nickname); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $father->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -247,6 +285,12 @@ class ManageUserFamiliesTest extends TestCase ]); $this->assertEquals($mother->nickname, $user->fresh()->mother->nickname); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $mother->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -273,6 +317,12 @@ class ManageUserFamiliesTest extends TestCase 'marriage_date' => '2010-01-01', 'manager_id' => $user->id, ]); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $wife->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ @@ -299,6 +349,12 @@ class ManageUserFamiliesTest extends TestCase 'marriage_date' => '2010-03-03', 'manager_id' => $user->id, ]); + + $this->seeInDatabase('family_connections', [ + 'requester_id' => $user->id, + 'requested_id' => $husband->id, + 'status_id' => FamilyConnection::STATUS_APPROVED, + ]); } /** @test */ diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index 000dba1..e94fdd6 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -3,10 +3,12 @@ namespace Tests\Unit; use App\Couple; +use App\FamilyConnection; use App\User; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Collection; +use Ramsey\Uuid\Uuid; use Tests\TestCase; class UserTest extends TestCase @@ -266,4 +268,38 @@ class UserTest extends TestCase $customer->birthday_remaining ); } + + /** @test */ + public function a_user_model_has_method_has_family_connection_request_to() + { + $john = factory(User::class)->create(); + $jane = factory(User::class)->create(); + + $this->assertFalse($john->hasFamilyConnectionRequestTo($jane)); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $john->id, + 'requested_id' => $jane->id, + ]); + + $this->assertTrue($john->hasFamilyConnectionRequestTo($jane)); + } + + /** @test */ + public function a_user_model_has_method_has_pending_family_connection_request_from() + { + $john = factory(User::class)->create(); + $jane = factory(User::class)->create(); + + $this->assertFalse($jane->hasPendingFamilyConnectionRequestFrom($john)); + + FamilyConnection::create([ + 'id' => Uuid::uuid4()->toString(), + 'requester_id' => $john->id, + 'requested_id' => $jane->id, + ]); + + $this->assertTrue($jane->hasPendingFamilyConnectionRequestFrom($john)); + } }