• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/processor/task/autocloser.php
  • Класс: BitrixTasksProcessorTaskAutoCloser
  • Вызов: AutoCloser::processEntity
public function processEntity($id, $data = array(), array $settings = array())
{
	$result = parent::processEntity($id, $data, $settings);

	// todo: this code will not work if someone creates already closed sub-task with this auto_close = on
	$id = intval($id);
	if(!$id || $data['STATUS'] != static::STATUS_COMPLETE)
	{
		return $result;
	}

	// todo: Impact class is TEMPORAL, it should be replaced with (or at least inherited from) BitrixTasksItemTask when ready
	//$taskImpact = new Impact($id, $this->getUserId());

	$worker = $this;

	$globalTree = $this->getParentTree($id);
	$prevData = $globalTree->getNodeData($id);

	if($prevData)
	{
		// close sub-tasks, if current task (andor sub tasks) has AUTO_CLOSE == Y
		if($prevData['AUTO_CLOSE'] == 'Y')
		{
			$subTree = $globalTree->getSubTree($id);
			$subTree->walkWidth(function($item, $itemId, $itemData, $parentId) use($subTree, $id, $worker) {

				//_print_r($itemData['TASK_ID'].' '.$itemData['TITLE'].' <- '.$parentId);

				$impactData = null;

				$parentData = $subTree->getNodeData($parentId);
				$parentImpact = $worker->getImpactById($parentId);
				if($parentImpact)
				{
					$parentData = $parentImpact;
				}

				if($parentData && $parentData['AUTO_CLOSE'] == 'Y')
				{
					if($itemData['STATUS'] != 5)
					{
						$itemData['ID'] = $itemData['__ID'];
						$impact = new Impact($itemData, $worker->getUserId());
						$impact->setDataUpdated(array('STATUS' => 5));

						$worker->addImpact($impact);
					}
				}
			});
		}

		// close parent tasks, if they have AUTO_CLOSE == Y
		$closeIndex = array();
		$globalTree->walkDepth(function($item, $itemId, $itemData, $parentId) use(&$closeIndex, $worker, $globalTree) {

			//_print_r($itemData['TASK_ID'].' '.$itemData['TITLE'].' <- '.$parentId);

			if(!array_key_exists($parentId, $closeIndex))
			{
				$closeIndex[$parentId] = $globalTree->getChildrenCount($parentId);
			}

			$impact = $worker->getImpactById($itemId);
			if($impact)
			{
				$itemData = $impact->getUpdatedData();
			}

			if($itemData['STATUS'] == 5) // was closed before or just closed
			{
				$closeIndex[$parentId]--;
			}

			if($parentId && !$closeIndex[$parentId] && !$worker->hasImpact($parentId))
			{
				// all children task closed
				$parentTaskData = $globalTree->getNodeData($parentId);

				if($parentTaskData['AUTO_CLOSE'] == 'Y')
				{
					$parentTaskData['ID'] = $parentTaskData['__ID'];
					$impact = new Impact($parentTaskData, $worker->getUserId());
					$impact->setDataUpdated(array('STATUS' => 5));

					$worker->addImpact($impact);
				}
			}
		});
	}

	$result->setData($this->affected);

	return $result;
}