Completed
Pull Request — master (#234)
by Beñat
04:07
created

CreateTaskHandler::becomeUserIdToDomainMemberId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Kreta package.
5
 *
6
 * (c) Beñat Espiña <[email protected]>
7
 * (c) Gorka Laucirica <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
declare(strict_types=1);
14
15
namespace Kreta\TaskManager\Application\Command\Project\Task;
16
17
use Kreta\TaskManager\Domain\Model\Organization\MemberId;
18
use Kreta\TaskManager\Domain\Model\Organization\Organization;
19
use Kreta\TaskManager\Domain\Model\Organization\OrganizationRepository;
20
use Kreta\TaskManager\Domain\Model\Project\Project;
21
use Kreta\TaskManager\Domain\Model\Project\ProjectDoesNotExistException;
22
use Kreta\TaskManager\Domain\Model\Project\ProjectId;
23
use Kreta\TaskManager\Domain\Model\Project\ProjectRepository;
24
use Kreta\TaskManager\Domain\Model\Project\Task\Task;
25
use Kreta\TaskManager\Domain\Model\Project\Task\TaskAlreadyExistsException;
26
use Kreta\TaskManager\Domain\Model\Project\Task\TaskAndTaskParentCannotBeTheSameException;
27
use Kreta\TaskManager\Domain\Model\Project\Task\TaskId;
28
use Kreta\TaskManager\Domain\Model\Project\Task\TaskParentDoesNotExistException;
29
use Kreta\TaskManager\Domain\Model\Project\Task\TaskPriority;
30
use Kreta\TaskManager\Domain\Model\Project\Task\TaskRepository;
31
use Kreta\TaskManager\Domain\Model\Project\Task\TaskTitle;
32
use Kreta\TaskManager\Domain\Model\Project\Task\UnauthorizedTaskActionException;
33
use Kreta\TaskManager\Domain\Model\User\UserId;
34
35
class CreateTaskHandler
36
{
37
    private $repository;
38
    private $projectRepository;
39
    private $organizationRepository;
40
41
    public function __construct(
42
        TaskRepository $repository,
43
        ProjectRepository $projectRepository,
44
        OrganizationRepository $organizationRepository
45
    ) {
46
        $this->repository = $repository;
47
        $this->projectRepository = $projectRepository;
48
        $this->organizationRepository = $organizationRepository;
49
    }
50
51
    public function __invoke(CreateTaskCommand $command)
52
    {
53
        $taskId = $command->taskId();
54
        $parentTaskId = $command->parentId();
55
56
        if (!$this->areTaskAndParentIdsDifferent($taskId, $parentTaskId)) {
57
            throw new TaskAndTaskParentCannotBeTheSameException();
58
        }
59
60
        $task = $this->repository->taskOfId(TaskId::generate($taskId));
61
        if ($this->doesTaskExist($task)) {
62
            throw new TaskAlreadyExistsException();
63
        }
64
65
        $parentTask = $this->repository->taskOfId(TaskId::generate($parentTaskId));
66
        if (!$this->doesParentTaskExist($parentTaskId, $parentTask)) {
67
            throw new TaskParentDoesNotExistException();
68
        }
69
70
        $projectId = $command->projectId();
71
        $project = $this->projectRepository->projectOfId(ProjectId::generate($projectId));
72
        if (!$this->doesProjectExist($project)) {
73
            throw new ProjectDoesNotExistException();
74
        }
75
76
        $organizationId = $project->organizationId();
77
        $creatorId = UserId::generate($command->creatorId());
78
        $assigneeId = UserId::generate($command->assigneeId());
79
80
        $organization = $this->organizationRepository->organizationOfId($organizationId);
81
        if (!$this->areUsersOrganizationMembers($organization, $creatorId, $assigneeId)) {
82
            throw new UnauthorizedTaskActionException();
83
        }
84
85
        $taskId = TaskId::generate($taskId);
86
        $title = new TaskTitle($command->title());
87
        $description = $command->description();
88
        $creator = $this->becomeUserIdToDomainMemberId($organization, $creatorId);
89
        $assignee = $this->becomeUserIdToDomainMemberId($organization, $assigneeId);
90
        $priority = new TaskPriority($command->priority());
91
        $projectId = ProjectId::generate($projectId);
92
        $parentTaskId = $this->parentTaskId($parentTaskId);
93
94
        $task = new Task($taskId, $title, $description, $creator, $assignee, $priority, $projectId, $parentTaskId);
95
        $this->repository->persist($task);
96
    }
97
98
    private function areTaskAndParentIdsDifferent($taskId, $parentTaskId) : bool
99
    {
100
        return ($taskId === null && $parentTaskId === null) || $parentTaskId !== $taskId;
101
    }
102
103
    private function doesTaskExist(Task $task = null) : bool
104
    {
105
        return $task instanceof Task;
106
    }
107
108
    private function doesParentTaskExist($parentTaskId, Task $parentTask = null) : bool
109
    {
110
        return null === $parentTaskId || $parentTask instanceof Task;
111
    }
112
113
    private function doesProjectExist(Project $project = null) : bool
114
    {
115
        return $project instanceof Project;
116
    }
117
118
    private function areUsersOrganizationMembers(Organization $organization, UserId $creatorId, UserId $assigneeId)
119
    {
120
        return $organization->isOrganizationMember($creatorId)
121
            && $organization->isOrganizationMember($assigneeId);
122
    }
123
124
    private function parentTaskId($parentTaskId)
125
    {
126
        return null === $parentTaskId ? null : TaskId::generate($parentTaskId);
127
    }
128
129
    private function becomeUserIdToDomainMemberId(Organization $organization, UserId $userId) : MemberId
130
    {
131
        return $organization->organizationMember($userId)->id();
132
    }
133
}
134