private function updateEfficiencyForUpdated(int $taskId): array
{
if (
!array_key_exists($taskId, $this->originData)
|| !array_key_exists($taskId, $this->modifiedData)
)
{
return [];
}
/** @var EventResource $oldTask */
$oldTask = $this->originData[$taskId];
/** @var EventResource $newTask */
$newTask = $this->modifiedData[$taskId];
if (
!$oldTask
|| !$newTask
)
{
return [];
}
$oldStatus = $oldTask->getStatus();
$newStatus = $newTask->getStatus();
$statusChanged = $oldStatus !== $newStatus;
/** @var DateTime $oldDeadline */
$oldDeadline = $oldTask->getDeadline();
/** @var DateTime $newDeadline */
$newDeadline = $newTask->getDeadline();
$deadlineChanged =
(!$oldDeadline && $newDeadline)
|| ($oldDeadline && !$newDeadline)
|| ($oldDeadline && $newDeadline && $oldDeadline->isNotEqualTo($newDeadline))
;
$isViolation = ($deadlineChanged ? $newTask->isExpired() : $oldTask->isExpired());
$oldGroupId = $oldTask->getGroupId();
$newGroupId = $newTask->getGroupId();
$groupChanged = $oldGroupId !== $newGroupId;
$groupId = ($groupChanged ? $newGroupId : $oldGroupId);
$oldMembers = $oldTask->getMembersAsArray();
$newMembers = $newTask->getMembersAsArray();
$oldResponsibleId = current($oldMembers[MemberTable::MEMBER_TYPE_RESPONSIBLE]);
$newResponsibleId = current($newMembers[MemberTable::MEMBER_TYPE_RESPONSIBLE]);
$responsibleChanged = $oldResponsibleId !== $newResponsibleId;
$oldAccomplices = $oldMembers[MemberTable::MEMBER_TYPE_ACCOMPLICE];
$newAccomplices = $newMembers[MemberTable::MEMBER_TYPE_ACCOMPLICE];
$accomplicesIn = array_diff($newAccomplices, $oldAccomplices);
$accomplicesOut = array_diff($oldAccomplices, $newAccomplices);
$allAccomplices = array_unique(array_merge($oldAccomplices, $newAccomplices));
$accomplicesChanged = $oldAccomplices !== $newAccomplices;
$oldTaskData = [
'ID' => $taskId,
'TITLE' => $newTask->getTitle(),
'DEADLINE' => $newTask->getDeadline(),
'CREATED_BY' => current($oldMembers[MemberTable::MEMBER_TYPE_ORIGINATOR]),
];
$newTaskData = [
'ID' => $taskId,
'TITLE' => $newTask->getTitle(),
'DEADLINE' => $newTask->getDeadline(),
'CREATED_BY' => current($newMembers[MemberTable::MEMBER_TYPE_ORIGINATOR]),
];
$responsibleModified = false;
$accomplicesModified = false;
$canProceed = false;
$statusesCompleted = [Status::DEFERRED, Status::COMPLETED, Status::SUPPOSEDLY_COMPLETED];
$statusesInProgress = [Status::NEW, Status::PENDING, Status::IN_PROGRESS];
$processedMembers = [];
// TASK DEFERRED OR COMPLETED
if ($statusChanged && in_array($newStatus, $statusesCompleted, true))
{
Effective::repair($taskId);
$this->modifyEfficiencyForResponsible($oldResponsibleId, $oldTaskData, $oldGroupId, false);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
foreach ($oldAccomplices as $userId)
{
if ($userId !== $oldResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $oldTaskData, $oldGroupId, false);
$processedMembers[$userId] = $userId;
}
}
if ($responsibleChanged)
{
$this->modifyEfficiencyForResponsible($newResponsibleId, $newTaskData, $groupId, false);
$processedMembers[$newResponsibleId] = $newResponsibleId;
}
if ($accomplicesChanged)
{
foreach ($accomplicesIn as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $newTaskData, $groupId, false);
$processedMembers[$userId] = $userId;
}
}
}
return $processedMembers;
}
// TASK RESTARTED
if (
$statusChanged
&& in_array($oldStatus, $statusesCompleted, true)
&& in_array($newStatus, $statusesInProgress, true)
)
{
if (!$responsibleChanged)
{
$this->modifyEfficiencyForResponsible($oldResponsibleId, $oldTaskData, $groupId, $isViolation);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
$responsibleModified = true;
}
if (!$accomplicesChanged)
{
foreach ($oldAccomplices as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $oldTaskData, $groupId, $isViolation);
$processedMembers[$userId] = $userId;
}
}
$accomplicesModified = true;
}
$canProceed = true;
}
if (!$canProceed && in_array($oldStatus, $statusesCompleted, true))
{
return $processedMembers;
}
// RESPONSIBLE CHANGED
if ($responsibleChanged)
{
if (
($activeViolations = Effective::checkActiveViolations($taskId, $oldResponsibleId))
&& in_array($oldResponsibleId, $newAccomplices, true)
)
{
EffectiveTable::update(
$activeViolations[0]['ID'],
['USER_TYPE' => MemberTable::MEMBER_TYPE_ACCOMPLICE, 'GROUP_ID' => $groupId]
);
}
else
{
Effective::repair($taskId, $oldResponsibleId, MemberTable::MEMBER_TYPE_RESPONSIBLE);
}
$this->modifyEfficiencyForResponsible($oldResponsibleId, $oldTaskData, $oldGroupId, false);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
if ($activeViolations = Effective::checkActiveViolations($taskId, $newResponsibleId))
{
EffectiveTable::update(
$activeViolations[0]['ID'],
['USER_TYPE' => MemberTable::MEMBER_TYPE_RESPONSIBLE, 'GROUP_ID' => $groupId]
);
$this->modifyEfficiencyForResponsible($newResponsibleId, $newTaskData, $groupId, false);
$processedMembers[$newResponsibleId] = $newResponsibleId;
}
else
{
$this->modifyEfficiencyForResponsible($newResponsibleId, $newTaskData, $groupId, $isViolation);
$processedMembers[$newResponsibleId] = $newResponsibleId;
}
$responsibleModified = true;
}
// ACCOMPLICES CHANGED
if ($accomplicesChanged)
{
foreach ($accomplicesOut as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
Effective::repair($taskId, $userId, MemberTable::MEMBER_TYPE_ACCOMPLICE);
$this->modifyEfficiencyForAccomplice($userId, $oldTaskData, $oldGroupId, false);
$processedMembers[$userId] = $userId;
}
}
foreach ($accomplicesIn as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $newTaskData, $groupId, $isViolation);
$processedMembers[$userId] = $userId;
}
}
}
// DEADLINE CHANGED
if ($deadlineChanged && !$isViolation)
{
Effective::repair($taskId);
if (!$responsibleModified)
{
$this->modifyEfficiencyForResponsible($oldResponsibleId, $newTaskData, $groupId, false);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
$responsibleModified = true;
}
if (!$accomplicesModified)
{
$accomplices = ($accomplicesChanged ? array_diff($newAccomplices, $accomplicesIn) : $allAccomplices);
foreach ($accomplices as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $newTaskData, $groupId, false);
$processedMembers[$userId] = $userId;
}
}
$accomplicesModified = true;
}
}
// GROUP CHANGED
if ($groupChanged)
{
if ($activeViolations = Effective::checkActiveViolations($taskId))
{
foreach ($activeViolations as $violation)
{
EffectiveTable::update($violation['ID'], ['GROUP_ID' => $newGroupId]);
}
if (!$responsibleModified)
{
$this->modifyEfficiencyForResponsible($oldResponsibleId, $newTaskData, $newGroupId, false);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
}
if (!$accomplicesModified)
{
$accomplices = ($accomplicesChanged ? array_diff($newAccomplices, $accomplicesIn) : $allAccomplices);
foreach ($accomplices as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $newTaskData, $newGroupId, false);
$processedMembers[$userId] = $userId;
}
}
}
}
else
{
if (!$responsibleModified)
{
$this->modifyEfficiencyForResponsible($oldResponsibleId, $newTaskData, $newGroupId, $isViolation);
$processedMembers[$oldResponsibleId] = $oldResponsibleId;
}
if (!$accomplicesModified)
{
$accomplices = ($accomplicesChanged ? array_diff($newAccomplices, $accomplicesIn) : $allAccomplices);
foreach ($accomplices as $userId)
{
if ($userId !== $oldResponsibleId && $userId !== $newResponsibleId)
{
$this->modifyEfficiencyForAccomplice($userId, $newTaskData, $newGroupId, $isViolation);
$processedMembers[$userId] = $userId;
}
}
}
}
}
return $processedMembers;
}