Passed
Push — developer ( dedd13...2a4a55 )
by Mariusz
14:30
created

ProjectMilestone_Module_Model   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
eloc 55
dl 0
loc 130
ccs 0
cts 58
cp 0
rs 10
c 0
b 0
f 0
1
<?php
2
/* +***********************************************************************************
3
 * The contents of this file are subject to the vtiger CRM Public License Version 1.0
4
 * ("License"); You may not use this file except in compliance with the License
5
 * The Original Code is:  vtiger CRM Open Source
6
 * The Initial Developer of the Original Code is vtiger.
7
 * Portions created by vtiger are Copyright (C) vtiger.
8
 * All Rights Reserved.
9
 * *********************************************************************************** */
10
11
class ProjectMilestone_Module_Model extends Vtiger_Module_Model
12
{
13
	/**
14
	 * Cache for estimated work time.
15
	 *
16
	 * @var float[]
17
	 */
18
	protected static $cacheEstimatedWorkTime = [];
19
20
	/**
21
	 * Calculate estimated work time.
22
	 *
23
	 * @param int   $id
24
	 * @param float $estimatedWorkTime
25
	 *
26
	 * @throws \App\Exceptions\AppException
27
	 *
28
	 * @return float
29
	 */
30
	public static function calculateEstimatedWorkTime(int $id, float $estimatedWorkTime = 0): float
31
	{
32
		if (isset(static::$cacheEstimatedWorkTime[$id])) {
33
			$estimatedWorkTime += static::$cacheEstimatedWorkTime[$id];
34
		} else {
35
			$progressInHours = 0;
36
			$tmpEstimatedWorkTime = 0;
37
			foreach (static::getChildren($id) as $child) {
38
				$tmpEstimatedWorkTime += static::calculateEstimatedWorkTime($child['id']);
39
			}
40
			static::calculateProgressOfTasks($id, $tmpEstimatedWorkTime, $progressInHours);
41
			static::$cacheEstimatedWorkTime[$id] = $tmpEstimatedWorkTime;
42
			$estimatedWorkTime += $tmpEstimatedWorkTime;
43
		}
44
		return $estimatedWorkTime;
45
	}
46
47
	/**
48
	 * Update progress milestone.
49
	 *
50
	 * @param int      $id
51
	 * @param float    $estimatedWorkTime
52
	 * @param float    $progressInHours
53
	 * @param int|null $callerId
54
	 *
55
	 * @throws \App\Exceptions\AppException
56
	 */
57
	public static function updateProgress(int $id, float $estimatedWorkTime = 0, float $progressInHours = 0, ?int $callerId = null)
58
	{
59
		$recordModel = Vtiger_Record_Model::getInstanceById($id);
60
		foreach (static::getChildren($id) as $child) {
61
			if ($callerId !== $child['id']) {
62
				$childEstimatedWorkTime = static::calculateEstimatedWorkTime($child['id']);
63
				$estimatedWorkTime += $childEstimatedWorkTime;
64
				$progressInHours += ($childEstimatedWorkTime * $child['projectmilestone_progress'] / 100);
65
			}
66
		}
67
		static::calculateProgressOfTasks($id, $estimatedWorkTime, $progressInHours);
68
		$projectProgress = $estimatedWorkTime ? round((100 * $progressInHours) / $estimatedWorkTime) : 0;
69
		$recordModel->set('projectmilestone_progress', $projectProgress);
70
		$recordModel->set('estimated_work_time', $estimatedWorkTime);
71
		$recordModel->save();
72
		if ($recordModel->isEmpty('parentid')) {
73
			static::$cacheEstimatedWorkTime[$id] = $estimatedWorkTime;
74
			if ($recordModel->get('projectid')) {
75
				Project_Module_Model::updateProgress($recordModel->get('projectid'));
76
			}
77
		} else {
78
			static::updateProgress(
79
				$recordModel->get('parentid'),
80
				$estimatedWorkTime,
81
				$progressInHours,
82
				$id
83
			);
84
		}
85
	}
86
87
	/**
88
	 * Function to get list view query for popup window.
89
	 *
90
	 * @param Vtiger_ListView_Model $listviewModel
91
	 * @param \App\QueryGenerator   $queryGenerator
92
	 */
93
	public function getQueryByRelatedField(Vtiger_ListView_Model $listviewModel, App\QueryGenerator $queryGenerator)
94
	{
95
		if ('Project' === $listviewModel->get('src_module') && !$listviewModel->isEmpty('filterFields')) {
96
			$filterFields = $listviewModel->get('filterFields');
97
			if (!empty($filterFields['projectid'])) {
98
				$queryGenerator->addNativeCondition(['projectid' => (int) $filterFields['projectid']]);
99
			}
100
		}
101
	}
102
103
	/**
104
	 * Get children by parent ID.
105
	 *
106
	 * @param int $id
107
	 *
108
	 * @return int[]
109
	 */
110
	protected static function getChildren(int $id): array
111
	{
112
		return (new \App\Db\Query())
113
			->select(['id' => 'vtiger_projectmilestone.projectmilestoneid', 'vtiger_projectmilestone.projectmilestone_progress'])
114
			->from('vtiger_projectmilestone')
115
			->innerJoin('vtiger_crmentity', 'vtiger_projectmilestone.projectmilestoneid = vtiger_crmentity.crmid')
116
			->where(['vtiger_crmentity.deleted' => [0, 2]])
117
			->andWhere(['vtiger_projectmilestone.parentid' => $id])->all();
118
	}
119
120
	/**
121
	 * Calculate the progress of tasks.
122
	 *
123
	 * @param int   $id
124
	 * @param float $estimatedWorkTime
125
	 * @param float $progressInHours
126
	 *
127
	 * @throws \App\Exceptions\AppException
128
	 */
129
	protected static function calculateProgressOfTasks(int $id, float &$estimatedWorkTime, float &$progressInHours)
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_VARIABLE, expecting T_STRING or T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED or T_NAME_RELATIVE on line 129 at column 68
Loading history...
130
	{
131
		$row = (new \App\Db\Query())
132
			->select([
133
				'estimated_work_time' => new \yii\db\Expression('SUM(vtiger_projecttask.estimated_work_time)'),
134
				'progress_in_hours' => new \yii\db\Expression('SUM(vtiger_projecttask.estimated_work_time * vtiger_projecttask.projecttaskprogress / 100)')
135
			])
136
			->from('vtiger_projecttask')
137
			->innerJoin('vtiger_crmentity', 'vtiger_projecttask.projecttaskid = vtiger_crmentity.crmid')
138
			->where(['vtiger_crmentity.deleted' => [0, 2]])
139
			->andWhere(['vtiger_projecttask.projectmilestoneid' => $id])
140
			->one();
141
		if (false !== $row && null !== $row['estimated_work_time']) {
142
			$estimatedWorkTime += (float) $row['estimated_work_time'];
143
			$progressInHours += (float) $row['progress_in_hours'];
144
		}
145
	}
146
}
147