organization_id !== $organization->id) { throw new AuthorizationException('Project does not belong to organization'); } if ($projectMember !== null && $projectMember->project->organization_id !== $organization->id) { throw new AuthorizationException('Project member does not belong to organization'); } } /** * Get project members for project * * @return ProjectMemberCollection * * @throws AuthorizationException * * @operationId getProjectMembers */ public function index(Organization $organization, Project $project): ProjectMemberCollection { $this->checkPermission($organization, 'project-members:view', $project); $projectMembers = ProjectMember::query() ->whereBelongsTo($project, 'project') ->paginate(config('app.pagination_per_page_default')); return new ProjectMemberCollection($projectMembers); } /** * Add project member to project * * @throws AuthorizationException|InactiveUserCanNotBeUsedApiException|UserIsAlreadyMemberOfProjectApiException * * @operationId createProjectMember */ public function store(Organization $organization, Project $project, ProjectMemberStoreRequest $request, BillableRateService $billableRateService): JsonResource { $this->checkPermission($organization, 'project-members:create', $project); $member = Member::findOrFail((string) $request->input('member_id')); if ($member->user->is_placeholder) { throw new InactiveUserCanNotBeUsedApiException; } if (ProjectMember::whereBelongsTo($project, 'project')->whereBelongsTo($member, 'member')->exists()) { throw new UserIsAlreadyMemberOfProjectApiException; } $projectMember = new ProjectMember; $projectMember->billable_rate = $request->getBillableRate(); $projectMember->member()->associate($member); $projectMember->user()->associate($member->user); $projectMember->project()->associate($project); $projectMember->save(); if ($request->getBillableRate() !== null) { $billableRateService->updateTimeEntriesBillableRateForProjectMember($projectMember); } return new ProjectMemberResource($projectMember); } /** * Update project member * * @throws AuthorizationException * * @operationId updateProjectMember */ public function update(Organization $organization, ProjectMember $projectMember, ProjectMemberUpdateRequest $request, BillableRateService $billableRateService): JsonResource { $this->checkPermission($organization, 'project-members:update', projectMember: $projectMember); $oldBillableRate = $projectMember->billable_rate; $projectMember->billable_rate = $request->getBillableRate(); $projectMember->save(); if ($oldBillableRate !== $request->getBillableRate()) { $billableRateService->updateTimeEntriesBillableRateForProjectMember($projectMember); } return new ProjectMemberResource($projectMember); } /** * Delete project member * * @throws AuthorizationException * * @operationId deleteProjectMember */ public function destroy(Organization $organization, ProjectMember $projectMember, BillableRateService $billableRateService): JsonResponse { $this->checkPermission($organization, 'project-members:delete', projectMember: $projectMember); $hadBillableRate = $projectMember->billable_rate !== null; $project = $projectMember->project; $member = $projectMember->member; $projectMember->delete(); if ($hadBillableRate) { $billableRateService->updateTimeEntriesBillableRateForMember($member); $billableRateService->updateTimeEntriesBillableRateForProject($project); $billableRateService->updateTimeEntriesBillableRateForOrganization($organization); } return response() ->json(null, 204); } }