Passed
Push — developer ( 2a4a55...bf97c6 )
by Radosław
18:45
created

Project_Module_Model::calculateEstimatedWorkTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 6
1
<?php
2
/**
3
 * Project module model class.
4
 *
5
 * @package   Module
6
 *
7
 * @copyright YetiForce S.A.
8
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
9
 * @author    Mariusz Krzaczkowski <[email protected]>
10
 */
11
class Project_Module_Model extends Vtiger_Module_Model
12
{
13
	/**
14
	 * Calculate estimated work time.
15
	 *
16
	 * @param int   $id
17
	 * @param float $estimatedWorkTime
18
	 *
19
	 * @throws \App\Exceptions\AppException
20
	 *
21
	 * @return float
22
	 */
23
	public static function calculateEstimatedWorkTime(int $id, float $estimatedWorkTime = 0): float
24
	{
25
		$progressInHours = 0;
26
		foreach (static::getChildren($id) as $child) {
27
			$estimatedWorkTime += static::calculateEstimatedWorkTime($child['id']);
28
		}
29
		static::calculateProgressOfMilestones($id, $estimatedWorkTime, $progressInHours);
30
		return $estimatedWorkTime;
31
	}
32
33
	/**
34
	 * Get children by parent ID.
35
	 *
36
	 * @param int $id
37
	 *
38
	 * @return int[]
39
	 */
40 1
	protected static function getChildren(int $id): array
41
	{
42 1
		return (new \App\Db\Query())
43 1
			->select(['id' => 'vtiger_project.projectid', 'vtiger_project.progress'])
44 1
			->from('vtiger_project')
45 1
			->innerJoin('vtiger_crmentity', 'vtiger_project.projectid = vtiger_crmentity.crmid')
46 1
			->where(['vtiger_crmentity.deleted' => [0, 2]])
47 1
			->andWhere(['vtiger_project.parentid' => $id])->all();
48
	}
49
50
	/**
51
	 * Calculate the progress of milestones.
52
	 *
53
	 * @param int   $id
54
	 * @param float $estimatedWorkTime
55
	 * @param float $progressInHours
56
	 *
57
	 * @throws \App\Exceptions\AppException
58
	 */
59 1
	protected static function calculateProgressOfMilestones(int $id, float &$estimatedWorkTime, float &$progressInHours)
60
	{
61 1
		$dataReader = (new \App\Db\Query())
62 1
			->select([
63 1
				'id' => 'vtiger_projectmilestone.projectmilestoneid',
64
				'projectmilestonename' => 'vtiger_projectmilestone.projectmilestonename',
65
				'projectmilestone_progress' => 'vtiger_projectmilestone.projectmilestone_progress',
66
			])
67 1
			->from('vtiger_projectmilestone')
68 1
			->innerJoin('vtiger_crmentity', 'vtiger_projectmilestone.projectmilestoneid = vtiger_crmentity.crmid')
69 1
			->where(['vtiger_crmentity.deleted' => [0, 2]])
70 1
			->andWhere(['vtiger_projectmilestone.projectid' => $id])
71 1
			->andWhere(['or', ['vtiger_projectmilestone.parentid' => 0], ['vtiger_projectmilestone.parentid' => null]])
72 1
			->createCommand()->query();
73 1
		while ($row = $dataReader->read()) {
74
			$milestoneEstimatedWorkTime = ProjectMilestone_Module_Model::calculateEstimatedWorkTime($row['id']);
75
			$estimatedWorkTime += $milestoneEstimatedWorkTime;
76
			$progressInHours += ($milestoneEstimatedWorkTime * (float) $row['projectmilestone_progress']) / 100;
77
		}
78 1
		$dataReader->close();
79 1
	}
80
81
	/** {@inheritdoc} */
82
	public function getSideBarLinks($linkParams)
83
	{
84
		$links = parent::getSideBarLinks($linkParams);
85
		$links['SIDEBARLINK'][] = Vtiger_Link_Model::getInstanceFromValues([
86
			'linktype' => 'SIDEBARLINK',
87
			'linklabel' => 'LBL_VIEW_GANTT',
88
			'linkurl' => 'index.php?module=Project&view=Gantt',
89
			'linkicon' => 'fas fa-briefcase',
90
		]);
91
		return $links;
92
	}
93
94
	/**
95
	 * Update progress in project.
96
	 *
97
	 * @param int      $id
98
	 * @param float    $estimatedWorkTime
99
	 * @param float    $progressInHours
100
	 * @param int|null $callerId
101
	 *
102
	 * @throws \App\Exceptions\AppException
103
	 *
104
	 * @return array
105
	 */
106
	public static function updateProgress(int $id, float $estimatedWorkTime = 0, float $progressInHours = 0, ?int $callerId = null): array
107
	{
108 1
		$recordModel = Vtiger_Record_Model::getInstanceById($id);
109
		foreach (static::getChildren($id) as $child) {
110 1
			if ($callerId !== $child['id']) {
111 1
				$childEstimatedWorkTime = static::calculateEstimatedWorkTime($child['id']);
112
				$estimatedWorkTime += $childEstimatedWorkTime;
113
				$progressInHours += ($childEstimatedWorkTime * $child['progress'] / 100);
114
			}
115
		}
116
		static::calculateProgressOfMilestones($id, $estimatedWorkTime, $progressInHours);
117
		$projectProgress = $estimatedWorkTime ? round((100 * $progressInHours) / $estimatedWorkTime) : 0;
118 1
		$recordModel->set('progress', $projectProgress);
119 1
		$recordModel->set('estimated_work_time', $estimatedWorkTime);
120 1
		$recordModel->save();
121 1
		if (!$recordModel->isEmpty('parentid') && $recordModel->get('parentid') !== $callerId) {
122 1
			static::updateProgress(
123 1
				$recordModel->get('parentid'),
124
				$estimatedWorkTime,
125
				$progressInHours,
126
				$id
127
			);
128
		}
129
		return [
130
			'estimatedWorkTime' => $estimatedWorkTime,
131
			'projectProgress' => $projectProgress
132 1
		];
133 1
	}
134
}
135