Skip to content

Commit 93d6a86

Browse files
agrossOnatcer
authored andcommitted
Show clients that are assigned to the employee, closes #893
1 parent 19a206d commit 93d6a86

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

app/Http/Controllers/Api/V1/ClientController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Http\Resources\V1\Client\ClientResource;
1313
use App\Models\Client;
1414
use App\Models\Organization;
15+
use App\Models\Project;
1516
use Illuminate\Auth\Access\AuthorizationException;
1617
use Illuminate\Http\JsonResponse;
1718
use Illuminate\Support\Carbon;
@@ -38,11 +39,23 @@ protected function checkPermission(Organization $organization, string $permissio
3839
public function index(Organization $organization, ClientIndexRequest $request): ClientCollection
3940
{
4041
$this->checkPermission($organization, 'clients:view');
42+
$canViewAllClients = $this->hasPermission($organization, 'clients:view:all');
43+
$user = $this->user();
4144

4245
$clientsQuery = Client::query()
4346
->whereBelongsTo($organization, 'organization')
4447
->orderBy('created_at', 'desc');
4548

49+
if (! $canViewAllClients) {
50+
$projectsQuery = Project::query()
51+
->whereBelongsTo($organization, 'organization')
52+
->visibleByEmployee($user)
53+
->distinct()
54+
->select('client_id');
55+
56+
$clientsQuery->whereIn('id', $projectsQuery);
57+
}
58+
4659
$filterArchived = $request->getFilterArchived();
4760
if ($filterArchived === 'true') {
4861
$clientsQuery->whereNotNull('archived_at');

app/Providers/JetstreamServiceProvider.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ protected function configurePermissions(): void
109109
'tags:update',
110110
'tags:delete',
111111
'clients:view',
112+
'clients:view:all',
112113
'clients:create',
113114
'clients:update',
114115
'clients:delete',
@@ -172,6 +173,7 @@ protected function configurePermissions(): void
172173
'tags:update',
173174
'tags:delete',
174175
'clients:view',
176+
'clients:view:all',
175177
'clients:create',
176178
'clients:update',
177179
'clients:delete',
@@ -232,6 +234,7 @@ protected function configurePermissions(): void
232234
'tags:update',
233235
'tags:delete',
234236
'clients:view',
237+
'clients:view:all',
235238
'clients:create',
236239
'clients:update',
237240
'clients:delete',
@@ -256,12 +259,13 @@ protected function configurePermissions(): void
256259
'projects:view',
257260
'tags:view',
258261
'tasks:view',
262+
'clients:view',
259263
'time-entries:view:own',
260264
'time-entries:create:own',
261265
'time-entries:update:own',
262266
'time-entries:delete:own',
263267
'organizations:view',
264-
])->description('Employees have the ability to read, create, and update their own time entries and they can see the projects that they are members of.');
268+
])->description('Employees have the ability to read, create, and update their own time entries, they can see the projects that they are members of and the clients they are assigned to.');
265269

266270
Jetstream::role(Role::Placeholder->value, 'Placeholder', [
267271
])->description('Placeholders are used for importing data. They cannot log in and have no permissions.');

tests/Unit/Endpoint/Api/V1/ClientEndpointTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function test_index_endpoint_returns_list_of_all_clients_of_organization_
3434
// Arrange
3535
$data = $this->createUserWithPermission([
3636
'clients:view',
37+
'clients:view:all',
3738
]);
3839
$clients = Client::factory()->forOrganization($data->organization)->randomCreatedAt()->createMany(4);
3940
Passport::actingAs($data->user);
@@ -57,11 +58,43 @@ public function test_index_endpoint_returns_list_of_all_clients_of_organization_
5758
);
5859
}
5960

61+
public function test_index_endpoint_returns_list_of_clients_assigned_to_employee_user(): void
62+
{
63+
// Arrange
64+
$data = $this->createUserWithPermission([
65+
'clients:view'
66+
]);
67+
68+
$clients = Client::factory()->forOrganization($data->organization)->createMany(2);
69+
$projectWithMembership1 = Project::factory()->forOrganization($data->organization)->forClient($clients->get(0))->addMember($data->member)->isPrivate()->create();
70+
$projectWithMembership2 = Project::factory()->forOrganization($data->organization)->forClient($clients->get(1))->addMember($data->member)->isPrivate()->create();
71+
72+
$otherClients = Client::factory()->forOrganization($data->organization)->createMany(2);
73+
$projectWithoutMembership = Project::factory()->forOrganization($data->organization)->forClient($otherClients->get(0))->isPrivate()->create();
74+
Passport::actingAs($data->user);
75+
76+
// Act
77+
$response = $this->getJson(route('api.v1.clients.index', [$data->organization->getKey()]));
78+
79+
// Assert
80+
$response->assertStatus(200);
81+
$response->assertJsonCount(2, 'data');
82+
$response->assertJson(fn (AssertableJson $json) => $json
83+
->has('data')
84+
->has('links')
85+
->has('meta')
86+
->count('data', 2)
87+
->where('data.0.id', $clients->get(0)->getKey())
88+
->where('data.1.id', $clients->get(1)->getKey())
89+
);
90+
}
91+
6092
public function test_index_endpoint_without_filter_archived_returns_only_non_archived_clients(): void
6193
{
6294
// Arrange
6395
$data = $this->createUserWithPermission([
6496
'clients:view',
97+
'clients:view:all',
6598
]);
6699
$archivedClients = Client::factory()->forOrganization($data->organization)->archived()->createMany(2);
67100
$nonArchivedClients = Client::factory()->forOrganization($data->organization)->createMany(2);
@@ -81,6 +114,7 @@ public function test_index_endpoint_with_filter_archived_true_returns_only_archi
81114
// Arrange
82115
$data = $this->createUserWithPermission([
83116
'clients:view',
117+
'clients:view:all',
84118
]);
85119
$archivedClients = Client::factory()->forOrganization($data->organization)->archived()->createMany(2);
86120
$nonArchivedClients = Client::factory()->forOrganization($data->organization)->createMany(2);
@@ -103,6 +137,7 @@ public function test_index_endpoint_with_filter_archived_false_returns_only_non_
103137
// Arrange
104138
$data = $this->createUserWithPermission([
105139
'clients:view',
140+
'clients:view:all',
106141
]);
107142
$archivedClients = Client::factory()->forOrganization($data->organization)->archived()->createMany(2);
108143
$nonArchivedClients = Client::factory()->forOrganization($data->organization)->createMany(2);
@@ -125,6 +160,7 @@ public function test_index_endpoint_with_filter_archived_all_returns_all_clients
125160
// Arrange
126161
$data = $this->createUserWithPermission([
127162
'clients:view',
163+
'clients:view:all',
128164
]);
129165
$archivedClients = Client::factory()->forOrganization($data->organization)->archived()->createMany(2);
130166
$nonArchivedClients = Client::factory()->forOrganization($data->organization)->createMany(2);

0 commit comments

Comments
 (0)