Completed
Pull Request — master (#382)
by Beñat
04:35
created

moveTaskReferencesFromUserToRemover()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 3
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\Organization;
16
17
use Kreta\TaskManager\Domain\Model\Organization\Member;
18
use Kreta\TaskManager\Domain\Model\Organization\Organization;
19
use Kreta\TaskManager\Domain\Model\Organization\OrganizationDoesNotExistException;
20
use Kreta\TaskManager\Domain\Model\Organization\OrganizationId;
21
use Kreta\TaskManager\Domain\Model\Organization\OrganizationRepository;
22
use Kreta\TaskManager\Domain\Model\Organization\Owner;
23
use Kreta\TaskManager\Domain\Model\Organization\UnauthorizedOrganizationActionException;
24
use Kreta\TaskManager\Domain\Model\Project\Task\Task;
25
use Kreta\TaskManager\Domain\Model\Project\Task\TaskRepository;
26
use Kreta\TaskManager\Domain\Model\Project\Task\TaskSpecificationFactory;
27
use Kreta\TaskManager\Domain\Model\User\UserId;
28
29
class RemoveOrganizationMemberToOrganizationHandler
30
{
31
    private $repository;
32
    private $taskRepository;
33
    private $taskSpecificationFactory;
34
35
    public function __construct(
36
        OrganizationRepository $repository,
37
        TaskRepository $taskRepository,
38
        TaskSpecificationFactory $taskSpecificationFactory
39
    ) {
40
        $this->repository = $repository;
41
        $this->taskRepository = $taskRepository;
42
        $this->taskSpecificationFactory = $taskSpecificationFactory;
43
    }
44
45
    public function __invoke(RemoveOrganizationMemberToOrganizationCommand $command) : void
46
    {
47
        $organizationId = OrganizationId::generate($command->organizationId());
48
        $removerId = UserId::generate($command->removerId());
49
        $userId = UserId::generate($command->userId());
50
51
        $organization = $this->repository->organizationOfId($organizationId);
52
53
        $this->checkOrganizationExists($organization);
54
        $this->checkRemoverIsOwner($organization, $removerId);
55
56
        $this->moveTaskReferencesFromUserToRemover($organization, $userId, $removerId);
57
        $organization->removeOrganizationMember($userId);
58
59
        $this->repository->persist($organization);
60
    }
61
62
    private function checkOrganizationExists(?Organization $organization) : void
63
    {
64
        if (null === $organization) {
65
            throw new OrganizationDoesNotExistException();
66
        }
67
    }
68
69
    private function checkRemoverIsOwner(Organization $organization, UserId $removerId) : void
70
    {
71
        if (!$organization->isOwner($removerId)) {
72
            throw new UnauthorizedOrganizationActionException();
73
        }
74
    }
75
76
    private function moveTaskReferencesFromUserToRemover(
77
        Organization $organization,
78
        UserId $userId,
79
        UserId $removerId
80
    ) : void {
81
        $member = $organization->organizationMember($userId);
82
        $remover = $organization->owner($removerId);
83
84
        $this->moveTaskReferencesFromAssigneeToRemover($member, $remover);
85
        $this->moveTaskReferencesFromReporterToRemover($member, $remover);
86
    }
87
88
    private function moveTaskReferencesFromAssigneeToRemover(Member $assignee, Owner $remover) : void
89
    {
90
        $tasks = $this->tasksOfAssignee($assignee);
91
        array_map(function (Task $task) use ($assignee, $remover) {
92
            $task->reassign($remover->id());
93
        }, $tasks);
94
    }
95
96
    private function tasksOfAssignee(Member $assignee) : array
97
    {
98
        $tasks = $this->taskRepository->query(
99
            $this->taskSpecificationFactory->buildByAssigneeSpecification(
100
                $assignee->id()
101
            )
102
        );
103
104
        return $tasks;
105
    }
106
107
    private function moveTaskReferencesFromReporterToRemover(Member $reporter, Owner $remover) : void
108
    {
109
        $tasks = $this->tasksOfReporter($reporter);
110
        array_map(function (Task $task) use ($reporter, $remover) {
111
            $task->changeReporter($remover->id());
112
        }, $tasks);
113
    }
114
115
    private function tasksOfReporter(Member $reporter) : array
116
    {
117
        $tasks = $this->taskRepository->query(
118
            $this->taskSpecificationFactory->buildByReporterSpecification(
119
                $reporter->id()
120
            )
121
        );
122
123
        return $tasks;
124
    }
125
}
126