Passed
Pull Request — master (#4)
by
unknown
01:45
created

SyncTimings::execute()   C

Complexity

Conditions 8
Paths 11

Size

Total Lines 37
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 18
nc 11
nop 2
1
<?php declare(strict_types=1);
2
3
namespace Syncer\Command;
4
5
use Syncer\Dto\InvoiceNinja\Task;
6
use Syncer\Dto\Toggl\TimeEntry;
7
use Syncer\Dto\InvoiceNinja\Client as InvoiceNinjaClientDto;
8
use Syncer\Dto\InvoiceNinja\Project as InvoiceNinjaProject;
9
use Syncer\InvoiceNinja\InvoiceNinjaClient;
10
use Syncer\Toggl\ReportsClient;
11
use Syncer\Toggl\TogglClient;
12
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Style\SymfonyStyle;
17
18
/**
19
 * Class SyncTimings
20
 * @package Syncer\Command
21
 *
22
 * @author Matthieu Calie <[email protected]>
23
 */
24
class SyncTimings extends Command
25
{
26
    /**
27
     * @var SymfonyStyle
28
     */
29
    private $io;
30
31
    /**
32
     * @var TogglClient
33
     */
34
    private $togglClient;
35
36
    /**
37
     * @var TogglClients
38
     */
39
    private $togglClients;
40
41
    /**
42
     * @var ReportsClient
43
     */
44
    private $reportsClient;
45
46
    /**
47
     * @var InvoiceNinjaClient
48
     */
49
    private $invoiceNinjaClient;
50
51
    /**
52
     * @var array
53
     */
54
    private $clients;
55
56
    /**
57
     * @var array
58
     */
59
    private $projects;
60
61
    /**
62
     * SyncTimings constructor.
63
     *
64
     * @param TogglClient $togglClient
65
     * @param ReportsClient $reportsClient
66
     * @param InvoiceNinjaClient $invoiceNinjaClient
67
     * @param array $clients
68
     * @param array $projects
69
     */
70
    public function __construct(
71
        TogglClient $togglClient,
72
        ReportsClient $reportsClient,
73
        InvoiceNinjaClient $invoiceNinjaClient,
74
        $clients,
75
        $projects,
76
        String $storageDir,
77
        String $storageFileName
78
    ) {
79
        $this->togglClient = $togglClient;
80
        $this->reportsClient = $reportsClient;
81
        $this->invoiceNinjaClient = $invoiceNinjaClient;
82
        $this->clients = $clients;
83
        $this->projects = $projects;
84
        $this->storageDir = $storageDir;
85
        $this->storageFileName = $storageFileName;
86
        $this->retrieveSentTimeEntries();
87
88
        parent::__construct();
89
    }
90
91
    /**
92
     * Configure the command
93
     */
94
    protected function configure()
95
    {
96
        $this
97
            ->setName('sync:timings')
98
            ->setDescription('Syncs timings from toggl to invoiceninja')
99
        ;
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    protected function execute(InputInterface $input, OutputInterface $output)
106
    {
107
        $this->io = new SymfonyStyle($input, $output);
108
        $workspaces = $this->togglClient->getWorkspaces();
109
110
        if (!is_array($workspaces) || count($workspaces) === 0) {
111
            $this->io->error('No workspaces to sync.');
112
113
            return;
114
        }
115
116
        foreach ($workspaces as $workspace) {
117
            $detailedReport = $this->reportsClient->getDetailedReport($workspace->getId());
118
            $this->clients = array_merge($this->clients, $this->retrieveClientsForWorkspace($workspace->getId()));
119
            $this->projects = array_merge($this->projects, $this->retrieveProjectsForWorkspace($workspace->getId()));
120
121
            foreach($detailedReport->getData() as $timeEntry) {
122
                $timeEntrySent = false;
123
124
                if (in_array($timeEntry->getId(), $this->sentTimeEntries))
125
                    continue;
126
127
                // Log the entry if the client key exists
128
                if ($this->timeEntryCanBeLoggedByConfig($this->clients, $timeEntry->getClient(), $timeEntrySent)) {
129
                    $this->logTask($timeEntry, $this->clients, $timeEntry->getClient(), $this->projects, $timeEntry->getProject());
130
131
                    $this->sentTimeEntries[] = $timeEntry->getId();
132
                    $timeEntrySent = true;
133
                }
134
135
                // Log the entry if the project key exists
136
                if ($this->timeEntryCanBeLoggedByConfig($this->projects, $timeEntry->getProject(), $timeEntrySent)) {
137
                    $this->logTask($timeEntry, $this->projects, $timeEntry->getProject());
138
139
                    $this->sentTimeEntries[] = $timeEntry->getId();
140
                    $timeEntrySent = true;
141
                }
142
143
                if ($timeEntrySent) {
144
                    $this->io->success('TimeEntry ('. $timeEntry->getDescription() . ') sent to InvoiceNinja');
145
                }
146
            }
147
        }
148
149
        $this->storeSentTimeEntries();
150
    }
151
152
    /**
153
     * @param array $config
154
     * @param string $entryKey
155
     * @param bool $hasAlreadyBeenSent
156
     *
157
     * @return bool
158
     */
159
    private function timeEntryCanBeLoggedByConfig(array $config, string $entryKey, bool $hasAlreadyBeenSent): bool
160
    {
161
        if ($hasAlreadyBeenSent) {
162
            return false;
163
        }
164
165
        return (is_array($config) && array_key_exists($entryKey, $config));
166
    }
167
168
    /**
169
     * @param TimeEntry $entry
170
     * @param array $clients
171
     * @param string $clientKey
172
     *
173
     * @return void
174
     */
175
    private function logTask(TimeEntry $entry, array $clients, string $clientKey, array $projects = NULL, string $projectKey = NULL)
176
    {
177
        $task = new Task();
178
179
        $task->setDescription($this->buildTaskDescription($entry));
180
        $task->setTimeLog($this->buildTimeLog($entry));
181
        $task->setClientId($clients[$clientKey]);
182
183
        if (isset($projects) && isset($projectKey))
184
            $task->setProjectId($projects[$projectKey]);
185
186
        $this->invoiceNinjaClient->saveNewTask($task);
187
    }
188
189
    /**
190
     * @param TimeEntry $entry
191
     *
192
     * @return string
193
     */
194
    private function buildTaskDescription(TimeEntry $entry): string
195
    {
196
        $description = '';
197
198
        if ($entry->getProject()) {
199
            $description .= $entry->getProject() . ': ';
200
        }
201
202
        $description .= $entry->getDescription();
203
204
        return $description;
205
    }
206
207
    /**
208
     * @param TimeEntry $entry
209
     *
210
     * @return string
211
     */
212
    private function buildTimeLog(TimeEntry $entry): string
213
    {
214
        $timeLog = [[
215
            $entry->getStart()->getTimestamp(),
216
            $entry->getEnd()->getTimestamp(),
217
        ]];
218
219
        return \GuzzleHttp\json_encode($timeLog);
220
    }
221
222
    private function retrieveClientsForWorkspace($workspaceId)
223
    {
224
        $this->togglClients = $this->togglClient->getClientsForWorkspace($workspaceId);
225
        $invoiceNinjaClients = $this->invoiceNinjaClient->getClients();
226
227
        $clients = Array();
228
229
        foreach ($this->togglClients as $togglClient)
230
        {
231
            if (!isset($this->projects[$togglProject->getName()]))
232
            {
233
                $found = false;
234
                    foreach ($invoiceNinjaClients as $invoiceNinjaClient)
235
                    {
236
                        if ($invoiceNinjaClient->getIsDeleted() == false && strcasecmp($togglClient->getName(), $invoiceNinjaClient->getName()) == 0)
237
                        {
238
                            $clients[$invoiceNinjaClient->getName()] = $invoiceNinjaClient->getId();
239
                            $found = true;
240
                        }
241
                    }
242
                }
243
                if (!$found)
244
                {
245
                    $client = new InvoiceNinjaClientDto();
246
247
                    $client->setName($togglClient->getName());
248
249
                    $clients[$togglClient->getName()] = $this->invoiceNinjaClient->saveNewClient($client)->getId();
250
251
                    $this->io->success('Client ('. $togglClient->getName() . ') created in InvoiceNinja');
252
                }
253
            }
254
        }
255
256
        return $clients;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_RETURN, expecting T_FUNCTION or T_CONST
Loading history...
257
    }
258
259
    private function retrieveProjectsForWorkspace($workspaceId)
260
    {
261
        $togglProjects = $this->togglClient->getProjectsForWorkspace($workspaceId);
262
        $invoiceNinjaProjects = $this->invoiceNinjaClient->getProjects();
263
264
        $projects = Array();
265
266
        foreach ($togglProjects as $togglProject)
267
        {
268
            if (!isset($this->projects[$togglProject->getName()]))
269
            {
270
                $found = false;
271
                foreach ($invoiceNinjaProjects as $invoiceNinjaProject)
272
                {
273
                    if ($invoiceNinjaProject->getIsDeleted() == false && strcasecmp($togglProject->getName(), $invoiceNinjaProject->getName()) == 0)
274
                    {
275
                        $projects[$invoiceNinjaProject->getName()] = $invoiceNinjaProject->getId();
276
                        $found = true;
277
                    }
278
                }
279
                if (!$found)
280
                {
281
                    $project = new InvoiceNinjaProject();
282
283
                    $project->setName($togglProject->getName());
284
285
                    foreach ($this->togglClients as $togglClient)
286
                    {
287
                        if ($togglClient->getWid() == $workspaceId && $togglClient->getId() == $togglProject->getCid())
288
                            $project->setClientId($this->clients[$togglClient->getName()]);
289
                    }
290
291
                    $projects[$togglProject->getName()] = $this->invoiceNinjaClient->saveNewProject($project)->getId();
292
293
                    $this->io->success('Project ('. $togglProject->getName() . ') created in InvoiceNinja');
294
                }
295
            }
296
        }
297
298
        return $projects;
299
    }
300
301
    private function retrieveSentTimeEntries()
302
    {
303
        if (!file_exists($this->storageDir))
304
            mkdir($this->storageDir, 0777, true);
305
306
        if (!file_exists($this->storageDir . $this->storageFileName))
307
            touch($this->storageDir . $this->storageFileName);
308
        
309
        $this->sentTimeEntries = unserialize(file_get_contents($this->storageDir . $this->storageFileName));
310
311
        if (!is_array($this->sentTimeEntries))
312
            $this->sentTimeEntries = Array();
313
314
        return $this->sentTimeEntries;
315
    }
316
317
    private function storeSentTimeEntries()
318
    {
319
        file_put_contents($this->storageDir . $this->storageFileName, serialize($this->sentTimeEntries));
320
    }
321
}
322