Test Failed
Pull Request — master (#38)
by Patrick
16:04 queued 12:22
created

ProjektronApi::findTaskIdToNeedle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 9
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of forecast.it.fill project.
7
 * (c) Patrick Jaja <[email protected]>
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace ForecastAutomation\ForecastClient\Business;
13
14
use ForecastAutomation\Activity\Shared\Dto\ActivityDtoCollection;
15
use ForecastAutomation\Cache\CacheFacade;
16
use ForecastAutomation\ForecastClient\Shared\Dto\ForecastConfigDto;
17
use ForecastAutomation\Log\LogFacade;
18
use GuzzleHttp\Client;
19
20
class ProjektronApi
21
{
22
    private const TASK_LIST_ENDPOINT = '/api/v2/projects/{{PROJECT_ID}}/tasks';
23
    private const TIME_REGISTRATIONS_ENDPOINT = '/api/v1/time_registrations';
24
25
    public static array $TASK_CACHE = [];
26
27
    public function __construct(
28
        private Client $guzzleClient,
29
        private ForecastConfigDto $forecastConfigDto,
30
        private LogFacade $logFacade,
31
        private CacheFacade $cacheFacade,
32
    ) {
33
        $this->warmTaskCache();
34
    }
35
36
    public function writeActivities(ActivityDtoCollection $activityDtoCollection): int
37
    {
38
        $savedActivities = 0;
39
        foreach ($activityDtoCollection as $activityDto) {
40
            $writeTimeRegistration = [
41
                'person' => (int) $this->forecastConfigDto->forecastPersonId,
42
                'task' => $this->findTaskIdToNeedle($activityDto->needle),
43
                'time_registered' => $activityDto->duration,
44
                'date' => $activityDto->created->format('Y-m-d'),
45
                'notes' => $activityDto->description,
46
            ];
47
            $writeResponse = $this->callPostApi(self::TIME_REGISTRATIONS_ENDPOINT, $writeTimeRegistration);
48
            $this->logFacade->info('activity sent to forecast.', (array) $writeResponse);
49
            ++$savedActivities;
50
        }
51
52
        return $savedActivities;
53
    }
54
55
    private function warmTaskCache(): array
56
    {
57
        static::$TASK_CACHE = $this->callGetApi(
58
            str_replace('{{PROJECT_ID}}', $this->forecastConfigDto->forecastProjectId, self::TASK_LIST_ENDPOINT)
59
        );
60
61
        return static::$TASK_CACHE;
62
    }
63
64
    private function callGetApi(string $path): array
65
    {
66
        if (! $this->cacheFacade->has($path)) {
67
            $res = $this->guzzleClient->request(
68
                'GET',
69
                $path,
70
                [
71
                    'headers' => ['X-FORECAST-API-KEY' => $this->forecastConfigDto->forecastApiKey],
72
                ]
73
            );
74
            $forecastResponse = json_decode((string) $res->getBody(), null, JSON_PARTIAL_OUTPUT_ON_ERROR, JSON_THROW_ON_ERROR);
75
            $this->cacheFacade->set($path, $forecastResponse);
76
        } else {
77
            $forecastResponse = $this->cacheFacade->get($path);
78
        }
79
80
        return $forecastResponse;
81
    }
82
83
    private function callPostApi(string $path, array $postData)
84
    {
85
        $res = $this->guzzleClient->request(
86
            'POST',
87
            $path,
88
            [
89
                'headers' => [
90
                    'X-FORECAST-API-KEY' => $this->forecastConfigDto->forecastApiKey,
91
                    'Content-Type' => 'application/json',
92
                    'Accept' => 'application/json',
93
                ],
94
                'body' => json_encode($postData, JSON_THROW_ON_ERROR),
95
            ]
96
        );
97
98
        return json_decode((string) $res->getBody(), null, JSON_PARTIAL_OUTPUT_ON_ERROR, JSON_THROW_ON_ERROR);
99
    }
100
101
    private function findTaskIdToNeedle(string $taskNeedle): int
102
    {
103
        foreach (static::$TASK_CACHE as $task) {
104
            if (str_contains($task->title, $taskNeedle)) {
105
                return $task->id;
106
            }
107
        }
108
109
        return (int) $this->forecastConfigDto->forecastFallbackTaskId;
110
    }
111
}
112