1 | <?php |
||||
2 | |||||
3 | namespace Godbout\Alfred\Time\Services; |
||||
4 | |||||
5 | use Carbon\Carbon; |
||||
6 | use Carbon\CarbonInterval; |
||||
7 | use Required\Harvest\Client; |
||||
8 | use Required\Harvest\Exception\NotFoundException; |
||||
9 | use Required\Harvest\Exception\AuthenticationException; |
||||
10 | use Required\Harvest\Exception\ValidationFailedException; |
||||
11 | |||||
12 | class Harvest extends TimerService |
||||
13 | { |
||||
14 | public $allowsEmptyProject = false; |
||||
15 | |||||
16 | public $allowsEmptyTag = false; |
||||
17 | |||||
18 | private $client; |
||||
19 | |||||
20 | |||||
21 | 15 | public function __construct($accountId, $apiToken) |
|||
22 | { |
||||
23 | 15 | $this->client = new Client(); |
|||
24 | |||||
25 | 15 | $this->client->authenticate($accountId, $apiToken); |
|||
26 | 15 | } |
|||
27 | |||||
28 | 3 | public function projects() |
|||
29 | { |
||||
30 | try { |
||||
31 | 3 | return array_column($this->client->projects()->all(['']), 'name', 'id'); |
|||
32 | 2 | } catch (AuthenticationException $e) { |
|||
33 | 2 | return []; |
|||
34 | } |
||||
35 | } |
||||
36 | |||||
37 | 4 | public function tags() |
|||
38 | { |
||||
39 | try { |
||||
40 | 4 | $taskAssignments = $this->client->projects()->taskAssignments()->all( |
|||
41 | 4 | (int) getenv('timer_project_id'), |
|||
42 | 4 | ['is_active' => true] |
|||
43 | ); |
||||
44 | |||||
45 | array_walk($taskAssignments, function ($taskAssignment) use (&$tags) { |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
46 | 2 | $tags[$taskAssignment['task']['id']] = $taskAssignment['task']['name']; |
|||
47 | 2 | }); |
|||
48 | |||||
49 | 2 | return $tags; |
|||
50 | 2 | } catch (AuthenticationException $e) { |
|||
51 | 2 | return []; |
|||
52 | } |
||||
53 | } |
||||
54 | |||||
55 | 1 | public function pastTimers() |
|||
56 | { |
||||
57 | try { |
||||
58 | 1 | $harvestTimers = $this->client->timeEntries()->all([ |
|||
59 | 1 | 'from' => Carbon::today()->subDays(30), |
|||
60 | 1 | 'to' => Carbon::today() |
|||
61 | ]); |
||||
62 | |||||
63 | 1 | return $this->convertToPastTimers($harvestTimers); |
|||
64 | } catch (AuthenticationException $e) { |
||||
65 | return []; |
||||
66 | } |
||||
67 | } |
||||
68 | |||||
69 | 6 | public function startTimer() |
|||
70 | { |
||||
71 | try { |
||||
72 | 6 | $timer = $this->client->timeEntries()->create([ |
|||
73 | 6 | 'notes' => getenv('timer_description'), |
|||
74 | 6 | 'project_id' => (int) getenv('timer_project_id'), |
|||
75 | 6 | 'task_id' => (int) getenv('timer_tag_id'), |
|||
76 | 6 | 'spent_date' => date('Y-m-d') |
|||
77 | ]); |
||||
78 | |||||
79 | 6 | if (! isset($timer['id'])) { |
|||
80 | 6 | return false; |
|||
81 | } |
||||
82 | } catch (ValidationFailedException $e) { |
||||
83 | return false; |
||||
84 | } |
||||
85 | |||||
86 | 6 | return $timer['id']; |
|||
87 | } |
||||
88 | |||||
89 | 5 | public function stopCurrentTimer() |
|||
90 | { |
||||
91 | 5 | if ($timerId = $this->runningTimer()) { |
|||
92 | 5 | $timer = $this->client->timeEntries()->stop($timerId); |
|||
93 | |||||
94 | 5 | if (! isset($timer['id'])) { |
|||
95 | throw new \Exception("Can't stop current running timer.", 1); |
||||
96 | } |
||||
97 | |||||
98 | 5 | return true; |
|||
99 | } |
||||
100 | |||||
101 | 1 | return false; |
|||
102 | } |
||||
103 | |||||
104 | 13 | public function runningTimer() |
|||
105 | { |
||||
106 | try { |
||||
107 | 13 | $timer = $this->client->timeEntries()->all(['is_running' => true]); |
|||
108 | |||||
109 | 13 | return $timer[0]['id'] ?? false; |
|||
110 | } catch (\Exception $e) { |
||||
111 | return false; |
||||
112 | } |
||||
113 | } |
||||
114 | |||||
115 | 1 | public function continueTimer($timerId) |
|||
116 | { |
||||
117 | 1 | $timer = $this->client->timeEntries()->restart($timerId); |
|||
118 | |||||
119 | 1 | return $timer['id'] ?? false; |
|||
120 | } |
||||
121 | |||||
122 | 6 | public function deleteTimer($timerId) |
|||
123 | { |
||||
124 | try { |
||||
125 | 6 | $this->client->timeEntries()->remove($timerId); |
|||
126 | } catch (NotFoundException $e) { |
||||
127 | return false; |
||||
128 | } |
||||
129 | |||||
130 | 6 | return true; |
|||
131 | } |
||||
132 | |||||
133 | 1 | protected function convertToPastTimers($harvestTimers) |
|||
134 | { |
||||
135 | return array_map(function ($harvestTimer) { |
||||
136 | 1 | return $this->buildPastTimerObject($harvestTimer); |
|||
137 | 1 | }, $harvestTimers); |
|||
138 | } |
||||
139 | |||||
140 | 1 | protected function buildPastTimerObject($harvestTimer) |
|||
141 | { |
||||
142 | 1 | $pastTimer['id'] = $harvestTimer['id']; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
143 | 1 | $pastTimer['description'] = $harvestTimer['notes']; |
|||
144 | 1 | $pastTimer['project_id'] = $harvestTimer['project']['id']; |
|||
145 | 1 | $pastTimer['project_name'] = $harvestTimer['project']['name']; |
|||
146 | 1 | $pastTimer['tag_id'] = $harvestTimer['task']['id']; |
|||
147 | 1 | $pastTimer['tags'] = $harvestTimer['task']['name']; |
|||
148 | 1 | $pastTimer['duration'] = CarbonInterval::seconds( |
|||
0 ignored issues
–
show
The method
Carbon\CarbonInterval::seconds() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
149 | 1 | floor($harvestTimer['hours'] * 3600) |
|||
150 | 1 | )->cascade()->format('%H:%I:%S'); |
|||
151 | |||||
152 | 1 | return (object) $pastTimer; |
|||
153 | } |
||||
154 | } |
||||
155 |