SyncTimings::configure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
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\InvoiceNinja\Client as InvoiceNinjaClient;
8
use Syncer\Toggl\ReportsClient;
9
use Syncer\Toggl\TogglClient;
10
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Style\SymfonyStyle;
15
16
/**
17
 * Class SyncTimings
18
 * @package Syncer\Command
19
 *
20
 * @author Matthieu Calie <[email protected]>
21
 */
22
class SyncTimings extends Command
23
{
24
    /**
25
     * @var SymfonyStyle
26
     */
27
    private $io;
28
29
    /**
30
     * @var TogglClient
31
     */
32
    private $togglClient;
33
34
    /**
35
     * @var ReportsClient
36
     */
37
    private $reportsClient;
38
39
    /**
40
     * @var InvoiceNinjaClient
41
     */
42
    private $invoiceNinjaClient;
43
44
    /**
45
     * @var array
46
     */
47
    private $clients;
48
49
    /**
50
     * @var array
51
     */
52
    private $projects;
53
54
    /**
55
     * SyncTimings constructor.
56
     *
57
     * @param TogglClient $togglClient
58
     * @param ReportsClient $reportsClient
59
     * @param InvoiceNinjaClient $invoiceNinjaClient
60
     * @param array $clients
61
     * @param array $projects
62
     */
63
    public function __construct(
64
        TogglClient $togglClient,
65
        ReportsClient $reportsClient,
66
        InvoiceNinjaClient $invoiceNinjaClient,
67
        $clients,
68
        $projects
69
    ) {
70
        $this->togglClient = $togglClient;
71
        $this->reportsClient = $reportsClient;
72
        $this->invoiceNinjaClient = $invoiceNinjaClient;
73
        $this->clients = $clients;
74
        $this->projects = $projects;
75
76
        parent::__construct();
77
    }
78
79
    /**
80
     * Configure the command
81
     */
82
    protected function configure()
83
    {
84
        $this
85
            ->setName('sync:timings')
86
            ->setDescription('Syncs timings from toggl to invoiceninja')
87
        ;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    protected function execute(InputInterface $input, OutputInterface $output)
94
    {
95
        $this->io = new SymfonyStyle($input, $output);
96
        $workspaces = $this->togglClient->getWorkspaces();
97
98
        if (!is_array($workspaces) || count($workspaces) === 0) {
99
            $this->io->error('No workspaces to sync.');
100
101
            return;
102
        }
103
104
        foreach ($workspaces as $workspace) {
105
            $detailedReport = $this->reportsClient->getDetailedReport($workspace->getId());
106
107
            foreach($detailedReport->getData() as $timeEntry) {
108
                $timeEntrySent = false;
109
110
                // Log the entry if the client key exists
111
                if ($this->timeEntryCanBeLoggedByConfig($this->clients, $timeEntry->getClient(), $timeEntrySent)) {
112
                    $this->logTask($timeEntry, $this->clients, $timeEntry->getClient());
113
114
                    $timeEntrySent = true;
115
                }
116
117
                // Log the entry if the project key exists
118
                if ($this->timeEntryCanBeLoggedByConfig($this->projects, $timeEntry->getProject(), $timeEntrySent)) {
119
                    $this->logTask($timeEntry, $this->projects, $timeEntry->getProject());
120
121
                    $timeEntrySent = true;
122
                }
123
124
                if ($timeEntrySent) {
125
                    $this->io->success('TimeEntry ('. $timeEntry->getDescription() . ') sent to InvoiceNinja');
126
                }
127
            }
128
        }
129
    }
130
131
    /**
132
     * @param array $config
133
     * @param string $entryKey
134
     * @param bool $hasAlreadyBeenSent
135
     *
136
     * @return bool
137
     */
138
    private function timeEntryCanBeLoggedByConfig(array $config, string $entryKey, bool $hasAlreadyBeenSent): bool
139
    {
140
        if ($hasAlreadyBeenSent) {
141
            return false;
142
        }
143
144
        return (is_array($config) && array_key_exists($entryKey, $config));
145
    }
146
147
    /**
148
     * @param TimeEntry $entry
149
     * @param array $config
150
     * @param string $key
151
     *
152
     * @return void
153
     */
154
    private function logTask(TimeEntry $entry, array $config, string $key)
155
    {
156
        $task = new Task();
157
158
        $task->setDescription($this->buildTaskDescription($entry));
159
        $task->setTimeLog($this->buildTimeLog($entry));
160
        $task->setClientId($config[$key]);
161
162
        $this->invoiceNinjaClient->saveNewTask($task);
163
    }
164
165
    /**
166
     * @param TimeEntry $entry
167
     *
168
     * @return string
169
     */
170
    private function buildTaskDescription(TimeEntry $entry): string
171
    {
172
        $description = '';
173
174
        if ($entry->getProject()) {
175
            $description .= $entry->getProject() . ': ';
176
        }
177
178
        $description .= $entry->getDescription();
179
180
        return $description;
181
    }
182
183
    /**
184
     * @param TimeEntry $entry
185
     *
186
     * @return string
187
     */
188
    private function buildTimeLog(TimeEntry $entry): string
189
    {
190
        $timeLog = [[
191
            $entry->getStart()->getTimestamp(),
192
            $entry->getEnd()->getTimestamp(),
193
        ]];
194
195
        return \GuzzleHttp\json_encode($timeLog);
196
    }
197
}
198