1 | <?php |
||||
2 | /** |
||||
3 | * WholePeriodChartGenerator.php |
||||
4 | * Copyright (c) 2019 [email protected] |
||||
5 | * |
||||
6 | * This file is part of Firefly III. |
||||
7 | * |
||||
8 | * Firefly III is free software: you can redistribute it and/or modify |
||||
9 | * it under the terms of the GNU General Public License as published by |
||||
10 | * the Free Software Foundation, either version 3 of the License, or |
||||
11 | * (at your option) any later version. |
||||
12 | * |
||||
13 | * Firefly III is distributed in the hope that it will be useful, |
||||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
16 | * GNU General Public License for more details. |
||||
17 | * |
||||
18 | * You should have received a copy of the GNU General Public License |
||||
19 | * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |
||||
20 | */ |
||||
21 | |||||
22 | namespace FireflyIII\Support\Chart\Category; |
||||
23 | |||||
24 | use Carbon\Carbon; |
||||
25 | use FireflyIII\Models\AccountType; |
||||
26 | use FireflyIII\Models\Category; |
||||
27 | use FireflyIII\Repositories\Account\AccountRepositoryInterface; |
||||
28 | use FireflyIII\Repositories\Category\CategoryRepositoryInterface; |
||||
29 | |||||
30 | /** |
||||
31 | * Class WholePeriodChartGenerator |
||||
32 | */ |
||||
33 | class WholePeriodChartGenerator |
||||
34 | { |
||||
35 | /** |
||||
36 | * @param Category $category |
||||
37 | * @param Carbon $start |
||||
38 | * @param Carbon $end |
||||
39 | * |
||||
40 | * @return array |
||||
41 | */ |
||||
42 | public function generate(Category $category, Carbon $start, Carbon $end): array |
||||
43 | { |
||||
44 | /** @var CategoryRepositoryInterface $repository */ |
||||
45 | $repository = app(CategoryRepositoryInterface::class); |
||||
46 | |||||
47 | /** @var AccountRepositoryInterface $accountRepository */ |
||||
48 | $accountRepository = app(AccountRepositoryInterface::class); |
||||
49 | |||||
50 | $types = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; |
||||
51 | $accounts = $accountRepository->getAccountsByType($types); |
||||
52 | $step = $this->calculateStep($start, $end); |
||||
53 | $chartData = []; |
||||
54 | $spent = []; |
||||
55 | $earned = []; |
||||
56 | |||||
57 | /** @var Carbon $current */ |
||||
58 | $current = clone $start; |
||||
59 | |||||
60 | while ($current <= $end) { |
||||
61 | $key = $current->format('Y-m-d'); |
||||
62 | $currentEnd = app('navigation')->endOfPeriod($current, $step); |
||||
63 | $spent[$key] = $repository->spentInPeriod($category, $accounts, $current, $currentEnd); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
64 | $earned[$key] = $repository->earnedInPeriod($category, $accounts, $current, $currentEnd); |
||||
0 ignored issues
–
show
$category of type FireflyIII\Models\Category is incompatible with the type Illuminate\Support\Collection expected by parameter $categories of FireflyIII\Repositories\...rface::earnedInPeriod() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
65 | $current = app('navigation')->addPeriod($current, $step, 0); |
||||
66 | } |
||||
67 | $currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned); |
||||
68 | |||||
69 | // generate chart data (for each currency) |
||||
70 | /** @var array $currency */ |
||||
71 | foreach ($currencies as $currency) { |
||||
72 | $code = $currency['currency_code']; |
||||
73 | $name = $currency['currency_name']; |
||||
74 | $chartData[sprintf('spent-in-%s', $code)] = [ |
||||
75 | 'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $name]), |
||||
76 | 'entries' => [], |
||||
77 | 'type' => 'bar', |
||||
78 | 'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red |
||||
79 | ]; |
||||
80 | |||||
81 | $chartData[sprintf('earned-in-%s', $code)] = [ |
||||
82 | 'label' => (string)trans('firefly.box_earned_in_currency', ['currency' => $name]), |
||||
83 | 'entries' => [], |
||||
84 | 'type' => 'bar', |
||||
85 | 'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green |
||||
86 | ]; |
||||
87 | } |
||||
88 | |||||
89 | /** @var Carbon $current */ |
||||
90 | $current = clone $start; |
||||
91 | |||||
92 | while ($current <= $end) { |
||||
93 | $key = $current->format('Y-m-d'); |
||||
94 | $label = app('navigation')->periodShow($current, $step); |
||||
95 | |||||
96 | /** @var array $currency */ |
||||
97 | foreach ($currencies as $currency) { |
||||
98 | $code = $currency['currency_code']; |
||||
99 | $spentInfoKey = sprintf('spent-in-%s', $code); |
||||
100 | $earnedInfoKey = sprintf('earned-in-%s', $code); |
||||
101 | $spentAmount = $spent[$key][$code]['spent'] ?? '0'; |
||||
102 | $earnedAmount = $earned[$key][$code]['earned'] ?? '0'; |
||||
103 | $chartData[$spentInfoKey]['entries'][$label] = round($spentAmount, $currency['currency_decimal_places']); |
||||
0 ignored issues
–
show
It seems like
$spentAmount can also be of type string ; however, parameter $val of round() does only seem to accept double , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
104 | $chartData[$earnedInfoKey]['entries'][$label] = round($earnedAmount, $currency['currency_decimal_places']); |
||||
105 | } |
||||
106 | $current = app('navigation')->addPeriod($current, $step, 0); |
||||
107 | } |
||||
108 | return $chartData; |
||||
109 | } |
||||
110 | |||||
111 | /** |
||||
112 | * TODO is a duplicate function. |
||||
113 | * |
||||
114 | * @param Carbon $start |
||||
115 | * @param Carbon $end |
||||
116 | * |
||||
117 | * @return string |
||||
118 | */ |
||||
119 | protected function calculateStep(Carbon $start, Carbon $end): string |
||||
120 | { |
||||
121 | |||||
122 | $step = '1D'; |
||||
123 | $months = $start->diffInMonths($end); |
||||
124 | if ($months > 3) { |
||||
125 | $step = '1W'; // @codeCoverageIgnore |
||||
126 | } |
||||
127 | if ($months > 24) { |
||||
128 | $step = '1M'; // @codeCoverageIgnore |
||||
129 | } |
||||
130 | if ($months > 100) { |
||||
131 | $step = '1Y'; // @codeCoverageIgnore |
||||
132 | } |
||||
133 | |||||
134 | return $step; |
||||
135 | } |
||||
136 | |||||
137 | /** |
||||
138 | * Loop array of spent/earned info, and extract which currencies are present. |
||||
139 | * Key is the currency ID. |
||||
140 | * |
||||
141 | * @param array $array |
||||
142 | * |
||||
143 | * @return array |
||||
144 | */ |
||||
145 | private function extractCurrencies(array $array): array |
||||
146 | { |
||||
147 | $return = []; |
||||
148 | foreach ($array as $info) { |
||||
149 | foreach ($info as $block) { |
||||
150 | $currencyId = $block['currency_id']; |
||||
151 | if (!isset($return[$currencyId])) { |
||||
152 | $return[$currencyId] = [ |
||||
153 | 'currency_id' => $block['currency_id'], |
||||
154 | 'currency_code' => $block['currency_code'], |
||||
155 | 'currency_name' => $block['currency_name'], |
||||
156 | 'currency_symbol' => $block['currency_symbol'], |
||||
157 | 'currency_decimal_places' => $block['currency_decimal_places'], |
||||
158 | ]; |
||||
159 | } |
||||
160 | } |
||||
161 | } |
||||
162 | |||||
163 | return $return; |
||||
164 | } |
||||
165 | |||||
166 | } |